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.
- checksums.yaml +4 -4
- data/_config.yml +2 -2
- data/_data/base/accordion_schema.yml +6 -0
- data/_data/base/announcement_schema.yml +1 -1
- data/_data/base/artwork_schema.yml +17 -3
- data/_data/base/bits_schema.yml +9 -4
- data/_data/base/breadcrumb_schema.yml +14 -0
- data/_data/base/breakingnews_schema.yml +1 -1
- data/_data/base/calendar_schema.yml +17 -2
- data/_data/base/card_schema.yml +2 -2
- data/_data/base/copyright_schema.yml +7 -17
- data/_data/base/copyvalue_schema.yml +4 -1
- data/_data/base/datatable_schema.yml +3 -3
- data/_data/base/download_schema.yml +42 -16
- data/_data/base/event_schema.yml +1 -1
- data/_data/base/footer_schema.yml +7 -6
- data/_data/base/highlight_schema.yml +7 -5
- data/_data/base/image_schema.yml +1 -1
- data/_data/base/link_schema.yml +13 -19
- data/_data/base/navbar_schema.yml +6 -0
- data/_data/base/preview_schema.yml +8 -4
- data/_data/base/project_schema.yml +4 -2
- data/_data/base/script_schema.yml +4 -4
- data/_data/base/shortcut_schema.yml +2 -2
- data/_data/base/social_schema.yml +2 -2
- data/_data/base/sponsors.yml +3 -2
- data/_data/base/sponsors_schema.yml +20 -0
- data/_data/base/title_schema.yml +14 -0
- data/_data/base/toc_schema.yml +16 -2
- data/_includes/base/accordion-item.html.liquid +11 -32
- data/_includes/base/accordion.html.liquid +3 -29
- data/_includes/base/announcement.html.liquid +8 -35
- data/_includes/base/artwork.html.liquid +5 -38
- data/_includes/base/backtotop.html.liquid +3 -42
- data/_includes/base/bits.html.liquid +26 -74
- data/_includes/base/breadcrumb.html.liquid +15 -49
- data/_includes/base/breakingnews.html.liquid +6 -43
- data/_includes/base/calendar-events.html.liquid +3 -37
- data/_includes/base/calendar-init.html.liquid +7 -63
- data/_includes/base/calendar.html.liquid +3 -34
- data/_includes/base/card.html.liquid +4 -44
- data/_includes/base/color-table.html.liquid +18 -4
- data/_includes/base/configuration_variables-default-cell.html.liquid +6 -50
- data/_includes/base/configuration_variables-nested.html.liquid +6 -7
- data/_includes/base/configuration_variables.html.liquid +9 -11
- data/_includes/base/content.html.liquid +7 -4
- data/_includes/base/copyright.html.liquid +8 -39
- data/_includes/base/copyvalue.html.liquid +3 -70
- data/_includes/base/datatable.html.liquid +4 -40
- data/_includes/base/download.html.liquid +12 -66
- data/_includes/base/download_architecture.html.liquid +29 -117
- data/_includes/base/download_commands.html.liquid +2 -14
- data/_includes/base/download_documentation.html.liquid +13 -47
- data/_includes/base/download_eol.html.liquid +5 -15
- data/_includes/base/download_filevalue.html.liquid +9 -49
- data/_includes/base/download_screenshots.html.liquid +10 -65
- data/_includes/base/download_sections.html.liquid +2 -19
- data/_includes/base/event.html.liquid +8 -63
- data/_includes/base/fontawesome.html.liquid +4 -38
- data/_includes/base/footer.html.liquid +9 -2
- data/_includes/base/head.html.liquid +6 -47
- data/_includes/base/highlight.html.liquid +4 -37
- data/_includes/base/image.html.liquid +5 -22
- data/_includes/base/link.html.liquid +38 -57
- data/_includes/base/locales.html.liquid +6 -26
- data/_includes/base/navbar.html.liquid +16 -45
- data/_includes/base/navindex.html.liquid +40 -111
- data/_includes/base/ogp.html.liquid +17 -83
- data/_includes/base/preview.html.liquid +18 -57
- data/_includes/base/project.html.liquid +4 -29
- data/_includes/base/shortcut.html.liquid +7 -37
- data/_includes/base/social.html.liquid +4 -42
- data/_includes/base/sponsors-cards.html.liquid +4 -55
- data/_includes/base/sponsors-carousel.html.liquid +11 -59
- data/_includes/base/sponsors-data.html.liquid +32 -0
- data/_includes/base/title.html.liquid +5 -42
- data/_includes/base/toc-generator.html.liquid +4 -0
- data/_includes/base/toc.html.liquid +28 -81
- data/_sass/base/_customization.scss +18 -0
- data/_sass/base/_preview.scss +5 -9
- data/assets/icons/favicon.ico +0 -0
- data/assets/js/base/backtotop.js +3 -3
- data/assets/js/base/copyvalue.js +15 -11
- data/assets/js/base/datatable.js +6 -13
- data/assets/js/base/highlight.js +46 -31
- metadata +2 -1
|
@@ -1,27 +1,25 @@
|
|
|
1
1
|
{% comment %}
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
configuration_variables: renders the page component's schema properties as a table, then one nested table per object or array-of-objects property.
|
|
3
|
+
Data: include.schema > site.data.<component>_schema > site.data.base.<component>_schema
|
|
4
|
+
Schema: src/YAML/configuration_variables_schema.yml
|
|
4
5
|
{% endcomment %}
|
|
5
6
|
|
|
6
7
|
{% assign component = page.component.name %}
|
|
7
|
-
{% assign property_name = "with_" | append: component %}
|
|
8
8
|
{% assign property_name_schema = component | append: "_schema" %}
|
|
9
9
|
{% assign property_schema = include.schema | default: site.data[property_name_schema] | default: site.data.base[property_name_schema] %}
|
|
10
10
|
|
|
11
|
-
{% assign col_name = include.col_name | default:
|
|
12
|
-
{% assign col_type = include.col_type | default:
|
|
13
|
-
{% assign col_default = include.col_default | default:
|
|
14
|
-
{% assign col_description = include.col_description | default:
|
|
11
|
+
{% assign col_name = include.col_name | default: site.data.base.configuration_variables_schema.properties.col_name.default %}
|
|
12
|
+
{% assign col_type = include.col_type | default: site.data.base.configuration_variables_schema.properties.col_type.default %}
|
|
13
|
+
{% assign col_default = include.col_default | default: site.data.base.configuration_variables_schema.properties.col_default.default %}
|
|
14
|
+
{% assign col_description = include.col_description | default: site.data.base.configuration_variables_schema.properties.col_description.default %}
|
|
15
15
|
|
|
16
16
|
{% assign columns = include.columns | default: property_schema.columns %}
|
|
17
17
|
|
|
18
18
|
{% if property_schema.properties %}
|
|
19
19
|
|
|
20
|
-
{% assign table_classes = "table dataTable" %}
|
|
21
|
-
|
|
22
20
|
<p>The <code>{{ page.component.name }}</code> {{ page.component.type }} understands the following configuration variables:</p>
|
|
23
21
|
|
|
24
|
-
<table class="
|
|
22
|
+
<table class="table dataTable">
|
|
25
23
|
<thead>
|
|
26
24
|
<tr>
|
|
27
25
|
<th scope="col">{{ col_name }}</th>
|
|
@@ -86,5 +84,5 @@ of separate, nested DataTables for complex properties.
|
|
|
86
84
|
{% endfor -%}
|
|
87
85
|
|
|
88
86
|
{% else %}
|
|
89
|
-
<p>The <code>{{ page.component.name }}</code> {{ page.component.type }}
|
|
87
|
+
<p>The <code>{{ page.component.name }}</code> {{ page.component.type }} doesn't have configuration variables.</p>
|
|
90
88
|
{% endif %}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
{% comment %}
|
|
2
|
+
content: renders the main element with the announcement, bits, event, breadcrumb, title, artwork, and toc rows, then the page content.
|
|
3
|
+
Data: include.data > page.with_content_data > site.data.content > site.data.base.content
|
|
4
|
+
Schema: src/YAML/content_schema.yml
|
|
5
|
+
{% endcomment %}
|
|
1
6
|
{%- assign with_content = include.with_content
|
|
2
7
|
| default: page.with_content
|
|
3
8
|
-%}
|
|
@@ -21,13 +26,11 @@
|
|
|
21
26
|
|
|
22
27
|
{%- assign row_class = include.row_class
|
|
23
28
|
| default: with_content_data.row_class
|
|
24
|
-
| default: content_schema.properties.with_content_data.properties.row_class.default
|
|
25
|
-
| default: 'row mb-3' -%}
|
|
29
|
+
| default: content_schema.properties.with_content_data.properties.row_class.default -%}
|
|
26
30
|
|
|
27
31
|
{%- assign col_class = include.col_class
|
|
28
32
|
| default: with_content_data.col_class
|
|
29
|
-
| default: content_schema.properties.with_content_data.properties.col_class.default
|
|
30
|
-
| default: 'col' -%}
|
|
33
|
+
| default: content_schema.properties.with_content_data.properties.col_class.default -%}
|
|
31
34
|
|
|
32
35
|
{%- if with_content -%}
|
|
33
36
|
<main class="{{ class }}">
|
|
@@ -1,34 +1,7 @@
|
|
|
1
1
|
{% comment %}
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Shows dynamic year, author, and links to Terms of Service, Privacy Policy, etc.
|
|
6
|
-
================================================================================
|
|
7
|
-
|
|
8
|
-
Design Logic:
|
|
9
|
-
- Dynamic year: automatically uses current year from site.time
|
|
10
|
-
- Legal links looping: flexible number of links in footer
|
|
11
|
-
- Reusable link component: consistent styling
|
|
12
|
-
- Capture-based rendering: builds complex link string before output
|
|
13
|
-
- Border separator styling: visual dividers between links
|
|
14
|
-
|
|
15
|
-
Required Inputs:
|
|
16
|
-
- author: Copyright holder name (e.g., "The CentOS Project")
|
|
17
|
-
|
|
18
|
-
Optional Inputs:
|
|
19
|
-
- legals: Array of legal link objects
|
|
20
|
-
- name: Link text (e.g., "Terms of Service")
|
|
21
|
-
- link: URL for legal document
|
|
22
|
-
- color: Link color (defaults to light)
|
|
23
|
-
- icon: Icon class (optional)
|
|
24
|
-
- class: Custom CSS classes (optional)
|
|
25
|
-
|
|
26
|
-
Data Source Hierarchy (priority):
|
|
27
|
-
1. include.data
|
|
28
|
-
2. page.with_copyright_data
|
|
29
|
-
3. site.data.copyright
|
|
30
|
-
4. site.data.base.copyright
|
|
31
|
-
================================================================================
|
|
2
|
+
copyright: renders the copyright line with the current year, the author, and the legal links.
|
|
3
|
+
Data: include.data > page.with_copyright_data > site.data.copyright > site.data.base.copyright
|
|
4
|
+
Schema: src/YAML/copyright_schema.yml
|
|
32
5
|
{% endcomment %}
|
|
33
6
|
|
|
34
7
|
{%- assign with_copyright = include.with_copyright
|
|
@@ -44,9 +17,6 @@ Data Source Hierarchy (priority):
|
|
|
44
17
|
{%- assign with_copyright_schema = site.data.base.copyright_schema.properties.with_copyright_data.properties %}
|
|
45
18
|
|
|
46
19
|
{%- if with_copyright %}
|
|
47
|
-
|
|
48
|
-
{%- comment %} === Presentation === {% endcomment %}
|
|
49
|
-
{%- comment %} --- Defaults --- {% endcomment %}
|
|
50
20
|
{%- assign copyright_author = with_copyright_data.author | default: with_copyright_schema.author.default %}
|
|
51
21
|
{%- assign copyright_legals = with_copyright_data.legals | default: with_copyright_schema.legals.default %}
|
|
52
22
|
|
|
@@ -54,20 +24,19 @@ Data Source Hierarchy (priority):
|
|
|
54
24
|
|
|
55
25
|
{%- capture copyright_links -%}
|
|
56
26
|
{%- for item in copyright_legals -%}
|
|
57
|
-
{%- assign
|
|
58
|
-
{%-
|
|
27
|
+
{%- assign copyright_link_class = item.class | default: copyright_legal_schema.class.default %}
|
|
28
|
+
{%- comment %} The span draws the separator outside the link, so the focus ring covers only the link text. Its border color matches the footer's default text color. {% endcomment -%}
|
|
29
|
+
<span class="border-start border-centos-purple-100 ms-2 ps-2">
|
|
59
30
|
{%- include base/link.html.liquid
|
|
60
31
|
class = copyright_link_class
|
|
61
32
|
name = item.name
|
|
62
33
|
link = item.link
|
|
63
|
-
color = item.color
|
|
64
34
|
role = item.role
|
|
65
35
|
icon = item.icon
|
|
66
36
|
icon_position = item.icon_position
|
|
67
37
|
-%}
|
|
38
|
+
</span>
|
|
68
39
|
{%- endfor -%}
|
|
69
|
-
{%- endcapture
|
|
70
|
-
|
|
71
|
-
{%- comment %} --- HTML --- {% endcomment %}
|
|
40
|
+
{%- endcapture %}
|
|
72
41
|
<p class="my-1">Copyright © {{ site.time | date: "%Y" }} {{ copyright_author }} {{ copyright_links }}</p>
|
|
73
42
|
{%- endif -%}
|
|
@@ -1,59 +1,7 @@
|
|
|
1
1
|
{% comment %}
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
================================================================================
|
|
6
|
-
|
|
7
|
-
Required Usage (in template):
|
|
8
|
-
<button type="button" class="copy-btn focus-ring" data-copy-value="{{ command | escape }}"
|
|
9
|
-
data-bs-toggle="tooltip" data-bs-title="Copy command">
|
|
10
|
-
<span class="fa-regular fa-copy"></span>
|
|
11
|
-
</button>
|
|
12
|
-
|
|
13
|
-
ACCESSIBILITY — every `.copy-btn` must be a `<button type="button">`. This
|
|
14
|
-
gives it keyboard focus and Enter/Space activation automatically.
|
|
15
|
-
`_customization.scss` resets the button's default border, background, and
|
|
16
|
-
padding back to a plain icon trigger. `.input-group-text.copy-btn`
|
|
17
|
-
(checksum and SRI-hash rows) is the exception — it keeps Bootstrap's own
|
|
18
|
-
addon box styling instead. Every `.copy-btn` also carries `focus-ring` so
|
|
19
|
-
its keyboard-focus ring matches the rest of the theme's interactive
|
|
20
|
-
elements — see `.focus-ring:focus:not(:focus-visible)` in
|
|
21
|
-
`_customization.scss`.
|
|
22
|
-
|
|
23
|
-
SECURITY — `data-copy-value` MUST always go through Liquid's `| escape` (or
|
|
24
|
-
equivalent HTML-attribute encoding) at the point where it is written, with no
|
|
25
|
-
exception for values that "look safe". The browser's own HTML parser decodes
|
|
26
|
-
entities (", &, ', …) in an attribute value as it parses the
|
|
27
|
-
tag, so by the time the JS reads `data-copy-value` it is already plain text —
|
|
28
|
-
there is no separate decoding step to rely on for sanitization. An unescaped,
|
|
29
|
-
attacker-influenced value (a query parameter, CMS field, etc.) placed
|
|
30
|
-
directly in data-copy-value breaks out of the HTML attribute at render time,
|
|
31
|
-
before this script ever runs.
|
|
32
|
-
|
|
33
|
-
Behavior:
|
|
34
|
-
- Visual feedback: checkmark icon + success tooltip
|
|
35
|
-
- Auto-reset: returns to original state after delay
|
|
36
|
-
- Clipboard API: native browser copy functionality
|
|
37
|
-
|
|
38
|
-
Required Inputs (from HTML element):
|
|
39
|
-
- class="copy-btn": Marks the element as a copy trigger
|
|
40
|
-
- data-copy-value: Text to copy to clipboard
|
|
41
|
-
|
|
42
|
-
Optional Inputs (from data objects):
|
|
43
|
-
- reset_delay: Milliseconds before reset (default varies by schema)
|
|
44
|
-
- checkmark_path: SVG path for success icon
|
|
45
|
-
- checkmark_viewbox: SVG viewBox for success icon
|
|
46
|
-
- success_message: Tooltip message on success
|
|
47
|
-
|
|
48
|
-
Data Source Hierarchy (in priority order):
|
|
49
|
-
1. include.data - Explicitly passed configuration
|
|
50
|
-
2. page.with_copyvalue_data - Page front matter
|
|
51
|
-
3. site.data.copyvalue - Site configuration
|
|
52
|
-
4. site.data.base.copyvalue - Theme defaults
|
|
53
|
-
|
|
54
|
-
Dependencies:
|
|
55
|
-
Bootstrap 5, FontAwesome 6+, Clipboard API (modern browsers)
|
|
56
|
-
================================================================================
|
|
2
|
+
copyvalue: loads the script that copies each .copy-btn's data-copy-value to the clipboard.
|
|
3
|
+
Data: include.data > page.with_copyvalue_data > site.data.copyvalue > site.data.base.copyvalue
|
|
4
|
+
Schema: src/YAML/copyvalue_schema.yml
|
|
57
5
|
{% endcomment %}
|
|
58
6
|
|
|
59
7
|
{%- assign with_copyvalue = include.with_copyvalue
|
|
@@ -69,30 +17,15 @@ Bootstrap 5, FontAwesome 6+, Clipboard API (modern browsers)
|
|
|
69
17
|
{%- assign with_copyvalue_schema = site.data.base.copyvalue_schema.properties.with_copyvalue_data.properties %}
|
|
70
18
|
|
|
71
19
|
{%- if with_copyvalue %}
|
|
72
|
-
|
|
73
|
-
{%- comment %} === Presentation === {% endcomment %}
|
|
74
|
-
|
|
75
|
-
{%- comment %} --- Defaults --- {% endcomment %}
|
|
76
20
|
{%- assign copyvalue_reset_delay = with_copyvalue_data.reset_delay | default: with_copyvalue_schema.reset_delay.default %}
|
|
77
21
|
{%- assign copyvalue_checkmark_path = with_copyvalue_data.checkmark_path | default: with_copyvalue_schema.checkmark_path.default %}
|
|
78
22
|
{%- assign copyvalue_checkmark_viewbox = with_copyvalue_data.checkmark_viewbox | default: with_copyvalue_schema.checkmark_viewbox.default %}
|
|
79
23
|
{%- assign copyvalue_success_message = with_copyvalue_data.success_message | default: with_copyvalue_schema.success_message.default %}
|
|
80
|
-
|
|
81
|
-
{%- comment %} --- HTML --- {% endcomment %}
|
|
82
|
-
<!-- Load Copy Value functionality with configuration via data attributes -->
|
|
83
24
|
<script id="centos-copyvalue"
|
|
84
|
-
{%- if with_copyvalue_data.reset_delay %}
|
|
85
25
|
data-reset-delay="{{ copyvalue_reset_delay }}"
|
|
86
|
-
{%- endif %}
|
|
87
|
-
{%- if with_copyvalue_data.checkmark_path %}
|
|
88
26
|
data-checkmark-path="{{ copyvalue_checkmark_path }}"
|
|
89
|
-
{%- endif %}
|
|
90
|
-
{%- if with_copyvalue_data.checkmark_viewbox %}
|
|
91
27
|
data-checkmark-viewbox="{{ copyvalue_checkmark_viewbox }}"
|
|
92
|
-
{%- endif %}
|
|
93
|
-
{%- if with_copyvalue_data.success_message %}
|
|
94
28
|
data-success-message="{{ copyvalue_success_message }}"
|
|
95
|
-
{%- endif %}
|
|
96
29
|
src="{{ site.baseurl }}/assets/js/base/copyvalue.min.js"
|
|
97
30
|
defer></script>
|
|
98
31
|
|
|
@@ -1,32 +1,7 @@
|
|
|
1
1
|
{% comment %}
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Initializes DataTables on all .dataTable elements with responsive design,
|
|
6
|
-
pagination, searching, and sorting.
|
|
7
|
-
================================================================================
|
|
8
|
-
|
|
9
|
-
Design Logic:
|
|
10
|
-
- CDN-based library loading with SRI integrity checks
|
|
11
|
-
- Responsive table design for mobile devices
|
|
12
|
-
- Smart pagination: only if table has >10 rows
|
|
13
|
-
- Automatic element detection: targets all .dataTable classes
|
|
14
|
-
- jQuery dependency: requires jQuery loaded first
|
|
15
|
-
|
|
16
|
-
Optional Inputs:
|
|
17
|
-
- type: "head" for CSS include, "script" for JavaScript
|
|
18
|
-
- version: DataTables version (e.g., "1.13.7")
|
|
19
|
-
- css_integrity, script_integrity: SRI integrity hashes
|
|
20
|
-
- page_length: Default rows per page (default: 10)
|
|
21
|
-
- length_menu: Pagination options
|
|
22
|
-
- data: DataTables configuration object
|
|
23
|
-
|
|
24
|
-
Data Source Hierarchy (priority):
|
|
25
|
-
1. include.data
|
|
26
|
-
2. page.with_datatable_data
|
|
27
|
-
3. site.data.datatable
|
|
28
|
-
4. site.data.base.datatable
|
|
29
|
-
================================================================================
|
|
2
|
+
datatable: loads DataTables from the CDN and enables it on every table.dataTable. head.html.liquid calls it with type="head" (CSS) and type="script" (JS).
|
|
3
|
+
Data: include.data > page.with_datatable_data > site.data.datatable > site.data.base.datatable
|
|
4
|
+
Schema: src/YAML/datatable_schema.yml
|
|
30
5
|
{% endcomment %}
|
|
31
6
|
|
|
32
7
|
{%- assign with_datatable = include.with_datatable
|
|
@@ -43,8 +18,6 @@ Data Source Hierarchy (priority):
|
|
|
43
18
|
|
|
44
19
|
{%- if with_datatable %}
|
|
45
20
|
|
|
46
|
-
{%- comment %} === Presentation === {% endcomment %}
|
|
47
|
-
{%- comment %} --- Defaults --- {% endcomment %}
|
|
48
21
|
{%- assign datatable_version = with_datatable_data.version | default: with_datatable_schema.version.default %}
|
|
49
22
|
{%- assign datatable_css_integrity = with_datatable_data.css_integrity | default: with_datatable_schema.css_integrity.default %}
|
|
50
23
|
{%- assign datatable_script_integrity = with_datatable_data.script_integrity | default: with_datatable_schema.script_integrity.default %}
|
|
@@ -56,24 +29,15 @@ Data Source Hierarchy (priority):
|
|
|
56
29
|
{%- endcapture %}
|
|
57
30
|
|
|
58
31
|
{%- capture html_datatable_script %}
|
|
59
|
-
<!-- DataTables Library -->
|
|
60
32
|
<script src="https://cdn.datatables.net/{{ datatable_version }}/datatables.min.js" integrity="{{ datatable_script_integrity }}" crossorigin="anonymous" referrerpolicy="no-referrer" defer></script>
|
|
61
|
-
|
|
62
|
-
<!-- Initialize DataTables with configuration via data attributes -->
|
|
63
33
|
<script id="centos-datatable"
|
|
64
|
-
{%- if with_datatable_data.page_length %}
|
|
65
34
|
data-page-length="{{ datatable_page_length }}"
|
|
66
|
-
{%- endif %}
|
|
67
|
-
{%- if with_datatable_data.length_menu %}
|
|
68
35
|
data-length-menu='{{ datatable_length_menu | split: "," | jsonify }}'
|
|
69
|
-
{%- endif %}
|
|
70
36
|
src="{{ site.baseurl }}/assets/js/base/datatable.min.js"
|
|
71
37
|
defer></script>
|
|
72
38
|
{%- endcapture %}
|
|
73
39
|
|
|
74
|
-
{%-
|
|
75
|
-
{%- assign type = include.type %}
|
|
76
|
-
{%- case type %}
|
|
40
|
+
{%- case include.type %}
|
|
77
41
|
{%- when "head" %}
|
|
78
42
|
{{ html_datatable_head }}
|
|
79
43
|
{%- when "script" %}
|
|
@@ -1,36 +1,7 @@
|
|
|
1
1
|
{% comment %}
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
component (like bits/sponsors), gated by with_download and resolved through
|
|
6
|
-
the standard 4-level fallback chain. Each entry in with_download_data is an
|
|
7
|
-
independent download "card" (e.g. one per distribution); include.title
|
|
8
|
-
filters to a single entry. Per-release sections (architecture/documentation/
|
|
9
|
-
eol/commands/screenshots) render automatically when their data is present —
|
|
10
|
-
no separate with_X flag per section, matching how card.html.liquid renders
|
|
11
|
-
its own sections only "if content". Shared between both render paths via
|
|
12
|
-
download_sections.html.liquid.
|
|
13
|
-
|
|
14
|
-
Alternative images (flavors) are not a section of this schema — a flavor
|
|
15
|
-
is just another download entry, linked via `documentation` or page
|
|
16
|
-
content rather than nested inside this one.
|
|
17
|
-
|
|
18
|
-
Data Source Hierarchy (in priority order):
|
|
19
|
-
1. include.data - Explicitly passed array
|
|
20
|
-
2. page.with_download_data - Page front matter
|
|
21
|
-
3. site.data.download - Site data
|
|
22
|
-
4. site.data.base.download - Theme defaults
|
|
23
|
-
|
|
24
|
-
Optional Inputs (from include):
|
|
25
|
-
- title: Render only the entry whose title matches exactly.
|
|
26
|
-
- id: HTML id prefix for the nav-pills tab selector (default: DownloadsCard-1).
|
|
27
|
-
- with_title: Set to false to skip the entry's own title heading, e.g. when
|
|
28
|
-
the calling page already presents it as a real markdown
|
|
29
|
-
heading immediately above the include (for TOC/anchor
|
|
30
|
-
navigation). Default: true.
|
|
31
|
-
- with_description: Set to false to skip the entry's own description text for the
|
|
32
|
-
same reason. Default: true.
|
|
33
|
-
================================================================================
|
|
2
|
+
download: renders each download entry, or only the one matching include.title, with its releases as tabs, or inline when there is one release.
|
|
3
|
+
Data: include.data > page.with_download_data > site.data.download > site.data.base.download
|
|
4
|
+
Schema: src/YAML/download_schema.yml
|
|
34
5
|
{% endcomment %}
|
|
35
6
|
|
|
36
7
|
{%- assign with_download = include.with_download
|
|
@@ -52,29 +23,17 @@ Optional Inputs (from include):
|
|
|
52
23
|
{%- continue %}
|
|
53
24
|
{%- endif %}
|
|
54
25
|
|
|
55
|
-
{%- comment %}
|
|
56
|
-
page's own URL (page.url already ends in "/" for pretty permalinks) rather
|
|
57
|
-
than a fixed schema default — every page gets its own collision-free
|
|
58
|
-
screenshot directory automatically, with no per-page front matter needed,
|
|
59
|
-
unless the entry explicitly overrides it. See download_schema.yml's
|
|
60
|
-
image_base_path description for the full rationale. {% endcomment %}
|
|
26
|
+
{%- comment %} Without an override, each page gets its own screenshot directory from page.url; see image_base_path in download_schema.yml. {% endcomment %}
|
|
61
27
|
{%- if entry.image_base_path and entry.image_base_path != "" %}
|
|
62
28
|
{%- assign entry_image_base_path = entry.image_base_path %}
|
|
63
29
|
{%- else %}
|
|
64
30
|
{%- assign entry_image_base_path = "/assets/img" | append: page.url %}
|
|
65
31
|
{%- endif %}
|
|
66
32
|
|
|
67
|
-
{%- comment %} entry.title feeds an HTML id
|
|
68
|
-
remove: chain (mirroring link.html.liquid's anchor assignment) missed
|
|
69
|
-
characters like em dashes, which the id spec forbids just the same —
|
|
70
|
-
slugify handles any non-alphanumeric character, not just a fixed list. {% endcomment %}
|
|
33
|
+
{%- comment %} slugify, not a remove: chain, because entry.title feeds an HTML id and can hold any character, such as an em dash. {% endcomment %}
|
|
71
34
|
{%- assign entry_title_id_safe = entry.title | slugify %}
|
|
72
35
|
|
|
73
|
-
{%-
|
|
74
|
-
{%- assign card_id = include.id | append: "-" | append: entry_title_id_safe | downcase | replace: " ", "-" %}
|
|
75
|
-
{%- else %}
|
|
76
|
-
{%- assign card_id = "DownloadsCard-1-" | append: entry_title_id_safe | downcase | replace: " ", "-" %}
|
|
77
|
-
{%- endif %}
|
|
36
|
+
{%- assign card_id = include.id | default: "DownloadsCard-1" | append: "-" | append: entry_title_id_safe | downcase | replace: " ", "-" %}
|
|
78
37
|
|
|
79
38
|
<div class="mb-1">
|
|
80
39
|
{%- assign single_release = nil %}
|
|
@@ -92,21 +51,13 @@ Optional Inputs (from include):
|
|
|
92
51
|
{{ entry.description | strip_newlines | markdownify }}
|
|
93
52
|
{%- endif %}
|
|
94
53
|
|
|
95
|
-
{%- comment %} A
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
project like CentOS Stream, which only ever has one active version —
|
|
99
|
-
the tab selector is skipped and that release's sections render
|
|
100
|
-
directly, since a single, permanently-active, non-interactive tab would
|
|
101
|
-
just be chrome with nothing to switch between. {% endcomment %}
|
|
102
|
-
{%- if entry.releases.size == 1 %}
|
|
103
|
-
{%- for release in entry.releases %}
|
|
104
|
-
{%- assign release_data = release[1] %}
|
|
54
|
+
{%- comment %} A single release renders its sections directly; a lone tab would have nothing to switch between. {% endcomment %}
|
|
55
|
+
{%- if single_release %}
|
|
56
|
+
{%- assign release_data = single_release[1] %}
|
|
105
57
|
{%- assign release_id = card_id | append: "-pills1" %}
|
|
106
58
|
<div id="{{ release_id }}" class="bg-white rounded py-3 border">
|
|
107
59
|
{%- include base/download_sections.html.liquid release_data=release_data release_id=release_id image_base_path=entry_image_base_path -%}
|
|
108
60
|
</div>
|
|
109
|
-
{%- endfor %}
|
|
110
61
|
{%- elsif entry.releases.size > 1 %}
|
|
111
62
|
<ul class="nav nav-pills mb-3 justify-content-start" id="{{ card_id }}-pills-tab" role="tablist">
|
|
112
63
|
{%- for release in entry.releases %}
|
|
@@ -117,19 +68,14 @@ Optional Inputs (from include):
|
|
|
117
68
|
data-bs-target="#{{ card_id }}-pills{{ forloop.index }}"
|
|
118
69
|
type="button"
|
|
119
70
|
role="tab"
|
|
120
|
-
aria-controls="{{ card_id }}-pills
|
|
121
|
-
{%- if forloop.first %} aria-selected="true"{% endif %}
|
|
71
|
+
aria-controls="{{ card_id }}-pills{{ forloop.index }}"
|
|
72
|
+
{%- if forloop.first %} aria-selected="true"{% else %} aria-selected="false"{% endif %}
|
|
122
73
|
>{%- if release[1].icon and release[1].icon != "" %}<i class="{{ release[1].icon }} me-1"></i>{% endif %}{{ release[0] }}</button>
|
|
123
74
|
</li>
|
|
124
75
|
{%- endfor %}
|
|
125
76
|
</ul>
|
|
126
77
|
|
|
127
|
-
{%- comment %}
|
|
128
|
-
not the inner .tab-pane — a .tab-pane's own corners are always square, so if
|
|
129
|
-
the rounded, filled look lived there instead, its corners would poke past
|
|
130
|
-
this div's border at each corner. overflow-hidden clips each pane to match.
|
|
131
|
-
Mirrors the single-release path above, which only ever needs one
|
|
132
|
-
rounded/bordered/filled box. {% endcomment %}
|
|
78
|
+
{%- comment %} Border and rounding live on .tab-content, not .tab-pane, whose square corners would poke past the border; overflow-hidden clips each pane. {% endcomment %}
|
|
133
79
|
<div class="tab-content border rounded overflow-hidden bg-white" id="{{ card_id }}-pills-tabContent">
|
|
134
80
|
{%- for release in entry.releases %}
|
|
135
81
|
{%- assign release_data = release[1] %}
|
|
@@ -1,37 +1,9 @@
|
|
|
1
1
|
{% comment %}
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
Purpose: One box per architecture, each with that architecture's own main
|
|
5
|
-
download/checksum/signature and mirror links — the single per-architecture
|
|
6
|
-
data source for a release. Called from download_sections.html.liquid.
|
|
7
|
-
|
|
8
|
-
Required Inputs:
|
|
9
|
-
- architecture: Map of architecture label (e.g. `x86_64`) to
|
|
10
|
-
{download, checksum, signature, checksum_value, signature_value,
|
|
11
|
-
mirrors: {iso, rpm, cloud, containers, vagrant, torrent}} — see
|
|
12
|
-
download_schema.yml for the full field-by-field description.
|
|
13
|
-
- release_id: The parent release's unique id, combined with each
|
|
14
|
-
architecture's own label to build a page-unique id_prefix for the
|
|
15
|
-
checksum/signature rows — see download_filevalue.html.liquid's id_prefix
|
|
16
|
-
note for why that's needed.
|
|
17
|
-
|
|
18
|
-
Within each box: icon + architecture title, then (if present) a Download
|
|
19
|
-
button, then (if present) one input-group row each for checksum and
|
|
20
|
-
signature, then (if present) the outline-primary mirror buttons — mirrors
|
|
21
|
-
is always the last section, so it never carries a trailing rule.
|
|
22
|
-
|
|
23
|
-
Design rationale for specific decisions lives as inline comments next to the
|
|
24
|
-
code they explain: the architecture map's shape versus mirrors/flavors
|
|
25
|
-
(above the grid loop below), the Download button's layout (above its
|
|
26
|
-
markup), the checksum/signature row design (above the download_filevalue
|
|
27
|
-
includes), and the responsive column/divider/orphan-row grid math (above
|
|
28
|
-
the column-count and orphan-detection blocks immediately below).
|
|
29
|
-
================================================================================
|
|
2
|
+
download_architecture: renders one box per architecture with its download button, checksum and signature rows, and mirror buttons.
|
|
3
|
+
Schema: src/YAML/download_schema.yml
|
|
30
4
|
{% endcomment %}
|
|
31
5
|
|
|
32
|
-
{%- comment %} Column count tracks
|
|
33
|
-
fills the row width, instead of a fixed row-cols-md-3 leaving a gap when there
|
|
34
|
-
are only 1 or 2 architectures. {% endcomment %}
|
|
6
|
+
{%- comment %} Column count tracks the architecture count so the grid always fills the row width. {% endcomment %}
|
|
35
7
|
{%- assign arch_count = include.architecture.size -%}
|
|
36
8
|
{%- case arch_count -%}
|
|
37
9
|
{%- when 1 -%}{%- assign arch_cols = 1 -%}
|
|
@@ -40,13 +12,7 @@ are only 1 or 2 architectures. {% endcomment %}
|
|
|
40
12
|
{%- else -%}{%- assign arch_cols = 4 -%}
|
|
41
13
|
{%- endcase -%}
|
|
42
14
|
|
|
43
|
-
{%- comment %}
|
|
44
|
-
figure out whether arch_count leaves a trailing partial row, and if so, the
|
|
45
|
-
0-based index where that partial row starts (orphan_*_start) and the width
|
|
46
|
-
each of its boxes should stretch to (orphan_*_width = 100% / remainder). A
|
|
47
|
-
value of -1 means "no orphan row at this breakpoint" — every box divides
|
|
48
|
-
evenly, or this breakpoint isn't reached at all (arch_cols too low).
|
|
49
|
-
{% endcomment %}
|
|
15
|
+
{%- comment %} orphan_*_start is the index where a trailing partial row begins and orphan_*_width the width its boxes stretch to; -1 means no partial row. {% endcomment %}
|
|
50
16
|
{%- assign row_cols_classes = "row-cols-1" -%}
|
|
51
17
|
{%- assign arch_divider_class = "" -%}
|
|
52
18
|
{%- assign orphan_sm_start = -1 -%}
|
|
@@ -56,12 +22,7 @@ evenly, or this breakpoint isn't reached at all (arch_cols too low).
|
|
|
56
22
|
{%- assign orphan_lg_start = -1 -%}
|
|
57
23
|
{%- assign orphan_lg_width = "" -%}
|
|
58
24
|
|
|
59
|
-
{%- comment %}
|
|
60
|
-
instead of jumping straight from 1 to arch_cols at a single breakpoint, so
|
|
61
|
-
stretching the window grows the grid progressively rather than in one hard
|
|
62
|
-
jump. Capped at arch_cols throughout — a 2-architecture release stops
|
|
63
|
-
adding columns at sm and never reaches 3 or 4, so it doesn't leave empty
|
|
64
|
-
gaps at wider viewports. {% endcomment %}
|
|
25
|
+
{%- comment %} Columns step up one per breakpoint, capped at arch_cols, so the grid grows progressively and never leaves empty gaps. {% endcomment %}
|
|
65
26
|
{%- if arch_cols >= 2 -%}
|
|
66
27
|
{%- assign row_cols_classes = row_cols_classes | append: " row-cols-sm-2" -%}
|
|
67
28
|
{%- assign arch_divider_class = "download-arch-divider-sm" -%}
|
|
@@ -99,30 +60,15 @@ gaps at wider viewports. {% endcomment %}
|
|
|
99
60
|
{%- endif -%}
|
|
100
61
|
{%- endif -%}
|
|
101
62
|
|
|
102
|
-
{%-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
e.g. a desktop spin) are deliberately NOT part of this grid — a flavor is
|
|
107
|
-
just another download entry, not a smaller variant of this one; model it as
|
|
108
|
-
its own with_download_data entry instead (releases keyed by flavor name
|
|
109
|
-
reuse the tab selector) and link the two via `documentation` or page
|
|
110
|
-
content — see examples/components/download-alternative-images.md.
|
|
111
|
-
{% endcomment %}
|
|
63
|
+
{%- assign download_mirror_keys = "iso,rpm,cloud,containers,vagrant,torrent" | split: "," %}
|
|
64
|
+
{%- assign download_mirror_labels = "ISO Mirrors,RPM Mirrors,Cloud Images,Container Images,Vagrant Boxes,Torrent" | split: "," %}
|
|
65
|
+
|
|
66
|
+
{%- comment %} Flavors are separate download entries, not part of this grid; see examples/components/download-alternative-images.md. {% endcomment %}
|
|
112
67
|
<div class="row {{ row_cols_classes }} g-3 align-items-start">
|
|
113
68
|
{%- for arch in include.architecture %}
|
|
114
69
|
{%- assign arch_name = arch[0] %}
|
|
115
70
|
{%- assign arch_data = arch[1] %}
|
|
116
|
-
{%- comment %}
|
|
117
|
-
class for the breakpoint the grid has reached (arch_divider_class, set
|
|
118
|
-
above per breakpoint) — a border-left shown only once the grid reaches
|
|
119
|
-
its full arch_cols width, not at every intermediate step. That's
|
|
120
|
-
deliberate: forloop.index0 modulo arch_cols only identifies "first in
|
|
121
|
-
its row" correctly once the grid is actually arch_cols-wide, so dividers
|
|
122
|
-
are hidden during the narrower intermediate steps rather than risk
|
|
123
|
-
misplaced lines while the grid is still at 2 or 3 columns. A box that
|
|
124
|
-
starts a wrapped second row (5+ architectures) correctly gets no divider
|
|
125
|
-
either, same as the very first box overall. {% endcomment %}
|
|
71
|
+
{%- comment %} Dividers show only at the full arch_cols width, the only width where forloop.index0 modulo arch_cols finds each row's first box. {% endcomment %}
|
|
126
72
|
{%- assign arch_row_position = forloop.index0 | modulo: arch_cols %}
|
|
127
73
|
{%- assign arch_col_class = "col" %}
|
|
128
74
|
{%- unless arch_row_position == 0 %}
|
|
@@ -144,16 +90,13 @@ content — see examples/components/download-alternative-images.md.
|
|
|
144
90
|
{%- endif -%}
|
|
145
91
|
|
|
146
92
|
{%- assign has_mirrors = false %}
|
|
147
|
-
{%-
|
|
148
|
-
{%-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
instead of this remove: chain, since slugify catches characters (e.g. em
|
|
155
|
-
dashes) the chain below doesn't. {% endcomment %}
|
|
156
|
-
{%- assign arch_name_id_safe = arch_name | remove: '"' | remove: "'" | remove: '<' | remove: '>' | remove: '&' | remove: '#' | remove: '?' | remove: '/' %}
|
|
93
|
+
{%- for mirror_key in download_mirror_keys %}
|
|
94
|
+
{%- if arch_data.mirrors[mirror_key] and arch_data.mirrors[mirror_key] != "" %}
|
|
95
|
+
{%- assign has_mirrors = true %}
|
|
96
|
+
{%- endif %}
|
|
97
|
+
{%- endfor %}
|
|
98
|
+
{%- comment %} slugify, not a remove: chain, because arch_name is a raw YAML key that feeds an HTML id and can hold any character. {% endcomment %}
|
|
99
|
+
{%- assign arch_name_id_safe = arch_name | slugify %}
|
|
157
100
|
{%- assign arch_id_prefix = include.release_id | default: "download" | append: "-" | append: arch_name_id_safe | downcase | replace: " ", "-" %}
|
|
158
101
|
<div class="{{ arch_col_class }}"{% if arch_orphan_style != "" %} style="{{ arch_orphan_style }}"{% endif %}>
|
|
159
102
|
<div class="d-flex flex-column align-items-start p-3 pt-1">
|
|
@@ -178,31 +121,17 @@ content — see examples/components/download-alternative-images.md.
|
|
|
178
121
|
{%- endif %}
|
|
179
122
|
|
|
180
123
|
{%- if has_download_button or has_checksum_row or has_signature_row %}
|
|
181
|
-
{%- comment %}
|
|
182
|
-
spacing between whichever rows are present is handled by the gap
|
|
183
|
-
alone — no per-row conditional mt-2 class needed (Bootstrap's spacing
|
|
184
|
-
scale maps 2 to the same 0.5rem for both mt-* and gap-*, so this is a
|
|
185
|
-
visual no-op versus a conditional-margin approach, just less
|
|
186
|
-
conditional logic). {% endcomment %}
|
|
124
|
+
{%- comment %} The wrapper's gap spaces whichever rows are present, so no row needs a conditional margin. {% endcomment %}
|
|
187
125
|
<div class="w-100 mb-3 pb-3 border-bottom d-flex flex-column gap-2">
|
|
188
126
|
{%- if has_download_button %}
|
|
189
|
-
{%- comment %}
|
|
190
|
-
.btn-group, so the button reflows instead of overflowing into the
|
|
191
|
-
neighboring architecture box at narrow column widths (e.g. the
|
|
192
|
-
4-column arrangement). Reuses base/link.html.liquid, the theme's
|
|
193
|
-
canonical link/button component. {% endcomment %}
|
|
127
|
+
{%- comment %} flex-wrap, not .btn-group, so the button reflows instead of overflowing into the next box at narrow widths. {% endcomment %}
|
|
194
128
|
<div class="d-flex flex-wrap gap-2" role="group" aria-label="Primary download actions">
|
|
195
|
-
{%- include base/link.html.liquid class="btn focus-ring btn-primary flex-fill text-start"
|
|
129
|
+
{%- include base/link.html.liquid class="btn focus-ring btn-primary flex-fill text-start" name="Download" link=arch_data.download icon="fa-solid fa-download" icon_position="start" -%}
|
|
196
130
|
</div>
|
|
197
131
|
{%- endif %}
|
|
198
132
|
|
|
199
133
|
{%- if has_checksum_row %}
|
|
200
|
-
{%- comment %}
|
|
201
|
-
are two views of the same file, merged into one input-group row
|
|
202
|
-
(rather than a link button plus a separate copy field) via
|
|
203
|
-
base/download_filevalue.html.liquid — see that file for the row's
|
|
204
|
-
own markup and its .link-primary / copy-value details.
|
|
205
|
-
{% endcomment %}
|
|
134
|
+
{%- comment %} The file link and its value are two views of one file, so they share one download_filevalue row. {% endcomment %}
|
|
206
135
|
{%- assign checksum_display = arch_data.checksum_value | default: arch_data.checksum %}
|
|
207
136
|
{%- include base/download_filevalue.html.liquid arch_name=arch_name field=arch_data.checksum field_value=checksum_display icon="fa-solid fa-shield-halved" label="checksum" id_prefix=arch_id_prefix -%}
|
|
208
137
|
{%- endif %}
|
|
@@ -215,32 +144,15 @@ content — see examples/components/download-alternative-images.md.
|
|
|
215
144
|
{%- endif %}
|
|
216
145
|
|
|
217
146
|
{%- if has_mirrors %}
|
|
218
|
-
{%- comment %}
|
|
219
|
-
in-page navigation, so each opens in a new tab (target="_blank") with
|
|
220
|
-
the same trailing external-link icon as the Documentation section's
|
|
221
|
-
buttons (base/download_documentation.html.liquid), rather than the
|
|
222
|
-
Download button's leading icon above — the leading icon there signals
|
|
223
|
-
the primary action; the trailing external icon here signals "leaves
|
|
224
|
-
the site". {% endcomment %}
|
|
147
|
+
{%- comment %} Mirrors leave the site, so they open in a new tab with a trailing external-link icon. {% endcomment %}
|
|
225
148
|
<div class="d-flex flex-wrap gap-2">
|
|
226
|
-
{%-
|
|
227
|
-
{%-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
{%-
|
|
233
|
-
{%- include base/link.html.liquid class="btn focus-ring btn-outline-primary flex-fill text-start" role="button" name="Cloud Images" link=arch_data.mirrors.cloud target="_blank" icon="fa-solid fa-up-right-from-square" icon_position="end" -%}
|
|
234
|
-
{%- endif %}
|
|
235
|
-
{%- if arch_data.mirrors.containers and arch_data.mirrors.containers != "" %}
|
|
236
|
-
{%- include base/link.html.liquid class="btn focus-ring btn-outline-primary flex-fill text-start" role="button" name="Container Images" link=arch_data.mirrors.containers target="_blank" icon="fa-solid fa-up-right-from-square" icon_position="end" -%}
|
|
237
|
-
{%- endif %}
|
|
238
|
-
{%- if arch_data.mirrors.vagrant and arch_data.mirrors.vagrant != "" %}
|
|
239
|
-
{%- include base/link.html.liquid class="btn focus-ring btn-outline-primary flex-fill text-start" role="button" name="Vagrant Boxes" link=arch_data.mirrors.vagrant target="_blank" icon="fa-solid fa-up-right-from-square" icon_position="end" -%}
|
|
240
|
-
{%- endif %}
|
|
241
|
-
{%- if arch_data.mirrors.torrent and arch_data.mirrors.torrent != "" %}
|
|
242
|
-
{%- include base/link.html.liquid class="btn focus-ring btn-outline-primary flex-fill text-start" role="button" name="Torrent" link=arch_data.mirrors.torrent target="_blank" icon="fa-solid fa-up-right-from-square" icon_position="end" -%}
|
|
243
|
-
{%- endif %}
|
|
149
|
+
{%- for mirror_key in download_mirror_keys %}
|
|
150
|
+
{%- assign mirror_link = arch_data.mirrors[mirror_key] %}
|
|
151
|
+
{%- assign mirror_label = download_mirror_labels[forloop.index0] %}
|
|
152
|
+
{%- if mirror_link and mirror_link != "" %}
|
|
153
|
+
{%- include base/link.html.liquid class="btn focus-ring btn-outline-primary flex-fill text-start" name=mirror_label link=mirror_link target="_blank" icon="fa-solid fa-up-right-from-square" icon_position="end" -%}
|
|
154
|
+
{%- endif %}
|
|
155
|
+
{%- endfor %}
|
|
244
156
|
</div>
|
|
245
157
|
{%- endif %}
|
|
246
158
|
</div>
|