jekyll-theme-zer0 0.1.8 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +128 -0
- data/README.md +195 -33
- data/_layouts/README.md +198 -0
- data/_layouts/blog.html +252 -143
- data/_layouts/collection.html +108 -27
- data/_layouts/default.html +74 -26
- data/_layouts/home.html +59 -9
- data/_layouts/index.html +47 -1
- data/_layouts/javascript.html +56 -1
- data/_layouts/journals.html +66 -3
- data/_layouts/landing.html +70 -11
- data/_layouts/root.html +61 -24
- metadata +57 -7
data/_layouts/blog.html
CHANGED
@@ -2,167 +2,276 @@
|
|
2
2
|
layout: root
|
3
3
|
source: "https://getbootstrap.com/docs/5.3/examples/blog/#"
|
4
4
|
---
|
5
|
+
<!--
|
6
|
+
===================================================================
|
7
|
+
BLOG LAYOUT - Modern blog homepage with featured content
|
8
|
+
===================================================================
|
9
|
+
|
10
|
+
File: blog.html
|
11
|
+
Path: _layouts/blog.html
|
12
|
+
Inherits: root.html
|
13
|
+
Purpose: Full-featured blog homepage with content organization
|
14
|
+
Source: Adapted from Bootstrap 5.3 blog example
|
15
|
+
|
16
|
+
Template Logic:
|
17
|
+
- Creates a magazine-style blog layout with multiple content sections
|
18
|
+
- Features breaking news/highlighted posts prominently
|
19
|
+
- Displays featured posts in a card grid layout
|
20
|
+
- Includes sidebar with recent posts, archives, and categories
|
21
|
+
- Implements responsive design for mobile and desktop
|
22
|
+
- Provides navigation between posts with pagination
|
23
|
+
|
24
|
+
Layout Structure:
|
25
|
+
1. Blog Header: Subscribe, logo/title, search, and sign-up
|
26
|
+
2. Navigation Bar: Dynamic navigation from site data
|
27
|
+
3. Hero Section: Most recent breaking news post
|
28
|
+
4. Featured Posts: Grid of featured content
|
29
|
+
5. Main Content: Blog content with pagination
|
30
|
+
6. Sidebar: Recent posts, archives, categories, external links
|
31
|
+
|
32
|
+
Content Logic:
|
33
|
+
- Breaking news: Posts with "breaking" category
|
34
|
+
- Featured posts: Posts with "featured: true" in frontmatter
|
35
|
+
- Recent posts: Latest 3 posts for sidebar
|
36
|
+
- Navigation: Dynamic from site.data.navigation.posts
|
37
|
+
|
38
|
+
Responsive Features:
|
39
|
+
- Mobile-first responsive grid system
|
40
|
+
- Image optimization with responsive classes
|
41
|
+
- Collapsible navigation and mobile-friendly layout
|
42
|
+
===================================================================
|
43
|
+
-->
|
5
44
|
|
45
|
+
<!-- ================================ -->
|
46
|
+
<!-- BLOG HEADER SECTION -->
|
47
|
+
<!-- ================================ -->
|
6
48
|
<div class="container">
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
49
|
+
<header class="border-bottom lh-1 py-3">
|
50
|
+
<div class="row flex-nowrap justify-content-between align-items-center">
|
51
|
+
<!-- Subscription Link -->
|
52
|
+
<div class="col-4 pt-1">
|
53
|
+
<a class="link-secondary" href="#">Subscribe</a>
|
54
|
+
</div>
|
55
|
+
|
56
|
+
<!-- Blog Title/Logo -->
|
57
|
+
<div class="col-4 text-center">
|
58
|
+
<a class="blog-header-logo text-body-emphasis text-decoration-none" href="#">
|
59
|
+
{{ page.title }}
|
60
|
+
</a>
|
61
|
+
</div>
|
62
|
+
|
63
|
+
<!-- Search and Sign-up -->
|
64
|
+
<div class="col-4 d-flex justify-content-end align-items-center">
|
65
|
+
<!-- Search Icon -->
|
66
|
+
<a class="link-secondary" href="#" aria-label="Search">
|
67
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="mx-3" role="img" viewBox="0 0 24 24">
|
68
|
+
<title>Search</title>
|
69
|
+
<circle cx="10.5" cy="10.5" r="7.5"/>
|
70
|
+
<path d="M21 21l-5.2-5.2"/>
|
71
|
+
</svg>
|
72
|
+
</a>
|
73
|
+
<a class="btn btn-sm btn-outline-secondary" href="#">Sign up</a>
|
74
|
+
</div>
|
75
|
+
</div>
|
76
|
+
</header>
|
23
77
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
78
|
+
<!-- ================================ -->
|
79
|
+
<!-- NAVIGATION BAR -->
|
80
|
+
<!-- ================================ -->
|
81
|
+
<!-- Dynamic navigation from site data configuration -->
|
82
|
+
<div class="nav-scroller py-1 mb-3 border-bottom">
|
83
|
+
<nav class="nav nav-underline justify-content-between">
|
84
|
+
{% for item in site.data.navigation.posts %}
|
85
|
+
<a class="nav-item nav-link link-body-emphasis" href="{{ item.url }}">
|
86
|
+
{{ item.title }}
|
87
|
+
</a>
|
88
|
+
{% endfor %}
|
89
|
+
</nav>
|
90
|
+
</div>
|
31
91
|
</div>
|
32
92
|
|
93
|
+
<!-- ================================ -->
|
94
|
+
<!-- MAIN CONTENT CONTAINER -->
|
95
|
+
<!-- ================================ -->
|
33
96
|
<main class="container">
|
97
|
+
|
98
|
+
<!-- ================================ -->
|
99
|
+
<!-- HERO SECTION - Breaking News -->
|
100
|
+
<!-- ================================ -->
|
101
|
+
<!-- Featured highlight of most recent breaking news post -->
|
102
|
+
{% assign breaking_news_posts = site.posts | where: "categories", "breaking" %}
|
103
|
+
{% assign most_recent_post = breaking_news_posts | first %}
|
34
104
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
</div>
|
45
|
-
<div class="col-lg-6">
|
46
|
-
<img src="{{ site.baseurl }}/{{ site.public_folder }}/{{ most_recent_post.preview }}" alt="Preview image" class="img-fluid">
|
47
|
-
</div>
|
48
|
-
</div>
|
49
|
-
</div>
|
50
|
-
|
51
|
-
<div class="row mb-2">
|
52
|
-
{% assign featured_posts = site.posts | where: "featured", true %}
|
53
|
-
{% for post in featured_posts %}
|
54
|
-
<div class="col-md-6">
|
55
|
-
<div class="row g-0 border rounded overflow-hidden flex-md-row mb-4 shadow-sm h-md-250 position-relative">
|
56
|
-
<div class="col p-4 d-flex flex-column position-static">
|
57
|
-
<strong class="d-inline-block mb-2 text-primary-emphasis">{{ post.categories[0] }}</strong>
|
58
|
-
<h3 class="mb-0">{{ post.title }}</h3>
|
59
|
-
<div class="mb-1 text-body-secondary">{{ post.date | date: "%b %d" }}</div>
|
60
|
-
<p class="card-text mb-auto">{{ post.excerpt | strip_html | truncate: 200 }}</p>
|
61
|
-
<a href="{{ site.baseurl }}{{ post.url }}" class="icon-link gap-1 icon-link-hover stretched-link">
|
62
|
-
Continue reading
|
63
|
-
<svg class="bi"><use xlink:href="#chevron-right"/></svg>
|
64
|
-
</a>
|
65
|
-
</div>
|
66
|
-
<div class="col-md-6 d-none d-lg-block">
|
67
|
-
<img src="{{ site.baseurl }}/{{ site.public_folder }}/{{ post.preview }}" alt="Post preview image" class="img-fluid">
|
68
|
-
</div>
|
69
|
-
</div>
|
70
|
-
</div>
|
71
|
-
{% endfor %}
|
72
|
-
</div>
|
73
|
-
|
74
|
-
<div class="row g-5">
|
75
|
-
<div class="col-md-8">
|
76
|
-
<h3 class="pb-4 mb-4 fst-italic border-bottom">
|
77
|
-
From the Firehose
|
78
|
-
</h3>
|
79
|
-
|
80
|
-
<article class="blog-post">
|
81
|
-
{{ content }}
|
82
|
-
</article>
|
83
|
-
|
84
|
-
<nav aria-label="Page navigation">
|
85
|
-
<ul class="pagination pagination-lg justify-content-center">
|
86
|
-
<li class="page-item">
|
87
|
-
{% if page.previous %}
|
88
|
-
<a class="page-link" href="{{ page.previous.url | prepend: site.baseurl }}">
|
89
|
-
Previous: {{ page.previous.title }}
|
105
|
+
<div class="p-4 p-md-5 mb-4 rounded text-body-emphasis bg-body-secondary">
|
106
|
+
<div class="row">
|
107
|
+
<!-- Breaking News Content -->
|
108
|
+
<div class="col-lg-6">
|
109
|
+
<h1 class="display-4 fst-italic">{{ most_recent_post.title }}</h1>
|
110
|
+
<p class="lead my-3">{{ most_recent_post.excerpt }}</p>
|
111
|
+
<p class="lead mb-0">
|
112
|
+
<a href="{{ site.baseurl }}{{ most_recent_post.url }}" class="text-body-emphasis fw-bold">
|
113
|
+
Continue reading...
|
90
114
|
</a>
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
<
|
96
|
-
{
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
<a class="page-link" href="#" aria-disabled="true">Next</a>
|
102
|
-
{% endif %}
|
103
|
-
</li>
|
104
|
-
</ul>
|
105
|
-
</nav>
|
115
|
+
</p>
|
116
|
+
</div>
|
117
|
+
|
118
|
+
<!-- Breaking News Image -->
|
119
|
+
<div class="col-lg-6">
|
120
|
+
<img src="{{ site.baseurl }}/{{ site.public_folder }}/{{ most_recent_post.preview }}"
|
121
|
+
alt="Preview image" class="img-fluid">
|
122
|
+
</div>
|
123
|
+
</div>
|
124
|
+
</div>
|
106
125
|
|
126
|
+
<!-- ================================ -->
|
127
|
+
<!-- FEATURED POSTS GRID -->
|
128
|
+
<!-- ================================ -->
|
129
|
+
<!-- Two-column grid of featured posts marked with 'featured: true' -->
|
130
|
+
<div class="row mb-2">
|
131
|
+
{% assign featured_posts = site.posts | where: "featured", true %}
|
132
|
+
{% for post in featured_posts %}
|
133
|
+
<div class="col-md-6">
|
134
|
+
<div class="row g-0 border rounded overflow-hidden flex-md-row mb-4 shadow-sm h-md-250 position-relative">
|
135
|
+
<!-- Post Content -->
|
136
|
+
<div class="col p-4 d-flex flex-column position-static">
|
137
|
+
<strong class="d-inline-block mb-2 text-primary-emphasis">
|
138
|
+
{{ post.categories[0] }}
|
139
|
+
</strong>
|
140
|
+
<h3 class="mb-0">{{ post.title }}</h3>
|
141
|
+
<div class="mb-1 text-body-secondary">{{ post.date | date: "%b %d" }}</div>
|
142
|
+
<p class="card-text mb-auto">{{ post.excerpt | strip_html | truncate: 200 }}</p>
|
143
|
+
<a href="{{ site.baseurl }}{{ post.url }}" class="icon-link gap-1 icon-link-hover stretched-link">
|
144
|
+
Continue reading
|
145
|
+
<svg class="bi"><use xlink:href="#chevron-right"/></svg>
|
146
|
+
</a>
|
147
|
+
</div>
|
148
|
+
|
149
|
+
<!-- Post Preview Image -->
|
150
|
+
<div class="col-md-6 d-none d-lg-block">
|
151
|
+
<img src="{{ site.baseurl }}/{{ site.public_folder }}/{{ post.preview }}"
|
152
|
+
alt="Post preview image" class="img-fluid">
|
153
|
+
</div>
|
154
|
+
</div>
|
155
|
+
</div>
|
156
|
+
{% endfor %}
|
107
157
|
</div>
|
108
158
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
159
|
+
<!-- ================================ -->
|
160
|
+
<!-- MAIN CONTENT AND SIDEBAR -->
|
161
|
+
<!-- ================================ -->
|
162
|
+
<div class="row g-5">
|
163
|
+
<!-- ========================== -->
|
164
|
+
<!-- MAIN CONTENT COLUMN -->
|
165
|
+
<!-- ========================== -->
|
166
|
+
<div class="col-md-8">
|
167
|
+
<h3 class="pb-4 mb-4 fst-italic border-bottom">From the Firehose</h3>
|
115
168
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
<li>
|
121
|
-
<a class="d-flex flex-column flex-lg-row gap-3 align-items-start align-items-lg-center py-3 link-body-emphasis text-decoration-none border-top" href="{{site.baseurl}}/{{ post.url }}">
|
122
|
-
<img class="bd-placeholder-img" src="{{ site.baseurl }}/{{ site.public_folder }}/{{ page.preview | default: site.og_image }}" width="50%" alt="Preview image">
|
123
|
-
<div class="col-lg-8">
|
124
|
-
<h6 class="mb-0">{{ post.title }}</h6>
|
125
|
-
<small class="text-body-secondary">{{ post.date | date: "%B %d, %Y" }}</small>
|
126
|
-
</div>
|
127
|
-
</a>
|
128
|
-
</li>
|
129
|
-
{% endfor %}
|
130
|
-
</ul>
|
131
|
-
</div>
|
169
|
+
<!-- Blog Post Content -->
|
170
|
+
<article class="blog-post">
|
171
|
+
{{ content }}
|
172
|
+
</article>
|
132
173
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
<
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
174
|
+
<!-- ========================== -->
|
175
|
+
<!-- POST PAGINATION -->
|
176
|
+
<!-- ========================== -->
|
177
|
+
<!-- Previous and Next page navigation -->
|
178
|
+
<nav aria-label="Page navigation">
|
179
|
+
<ul class="pagination pagination-lg justify-content-center">
|
180
|
+
<li class="page-item">
|
181
|
+
{% if page.previous %}
|
182
|
+
<a class="page-link" href="{{ page.previous.url | prepend: site.baseurl }}">
|
183
|
+
Previous: {{ page.previous.title }}
|
184
|
+
</a>
|
185
|
+
{% else %}
|
186
|
+
<a class="page-link" href="#" aria-disabled="true">Previous</a>
|
187
|
+
{% endif %}
|
188
|
+
</li>
|
189
|
+
<li class="page-item">
|
190
|
+
{% if page.next %}
|
191
|
+
<a class="page-link" href="{{ page.next.url | prepend: site.baseurl }}">
|
192
|
+
Next: {{ page.next.title }}
|
193
|
+
</a>
|
194
|
+
{% else %}
|
195
|
+
<a class="page-link" href="#" aria-disabled="true">Next</a>
|
196
|
+
{% endif %}
|
197
|
+
</li>
|
198
|
+
</ul>
|
199
|
+
</nav>
|
149
200
|
</div>
|
150
201
|
|
151
|
-
|
152
|
-
|
153
|
-
|
202
|
+
<!-- ========================== -->
|
203
|
+
<!-- SIDEBAR COLUMN -->
|
204
|
+
<!-- ========================== -->
|
205
|
+
<div class="col-md-4">
|
206
|
+
<div class="position-sticky" style="top: 2rem;">
|
207
|
+
|
208
|
+
<!-- About Section -->
|
209
|
+
<div class="p-4 mb-3 bg-body-tertiary rounded">
|
210
|
+
<h4 class="fst-italic">About</h4>
|
211
|
+
<p class="mb-0">
|
212
|
+
Customize this section to tell your visitors a little bit about your publication,
|
213
|
+
writers, content, or something else entirely. Totally up to you.
|
214
|
+
</p>
|
215
|
+
</div>
|
216
|
+
|
217
|
+
<!-- Recent Posts Section -->
|
218
|
+
<div>
|
219
|
+
<h4 class="fst-italic">Recent posts</h4>
|
220
|
+
<ul class="list-unstyled">
|
221
|
+
{% for post in site.posts limit:3 %}
|
222
|
+
<li>
|
223
|
+
<a class="d-flex flex-column flex-lg-row gap-3 align-items-start align-items-lg-center py-3 link-body-emphasis text-decoration-none border-top"
|
224
|
+
href="{{site.baseurl}}/{{ post.url }}">
|
225
|
+
<img class="bd-placeholder-img"
|
226
|
+
src="{{ site.baseurl }}/{{ site.public_folder }}/{{ page.preview | default: site.og_image }}"
|
227
|
+
width="50%" alt="Preview image">
|
228
|
+
<div class="col-lg-8">
|
229
|
+
<h6 class="mb-0">{{ post.title }}</h6>
|
230
|
+
<small class="text-body-secondary">{{ post.date | date: "%B %d, %Y" }}</small>
|
231
|
+
</div>
|
232
|
+
</a>
|
233
|
+
</li>
|
234
|
+
{% endfor %}
|
235
|
+
</ul>
|
236
|
+
</div>
|
237
|
+
|
238
|
+
<!-- Archives Section -->
|
239
|
+
<!-- Note: This section uses static links - consider making dynamic -->
|
240
|
+
<div class="p-4">
|
241
|
+
<h4 class="fst-italic">Archives</h4>
|
242
|
+
<ol class="list-unstyled mb-0">
|
243
|
+
<li><a href="#">March 2021</a></li>
|
244
|
+
<li><a href="#">February 2021</a></li>
|
245
|
+
<li><a href="#">January 2021</a></li>
|
246
|
+
<li><a href="#">December 2020</a></li>
|
247
|
+
<li><a href="#">November 2020</a></li>
|
248
|
+
<li><a href="#">October 2020</a></li>
|
249
|
+
<li><a href="#">September 2020</a></li>
|
250
|
+
<li><a href="#">August 2020</a></li>
|
251
|
+
<li><a href="#">July 2020</a></li>
|
252
|
+
<li><a href="#">June 2020</a></li>
|
253
|
+
<li><a href="#">May 2020</a></li>
|
254
|
+
<li><a href="#">April 2020</a></li>
|
255
|
+
</ol>
|
256
|
+
</div>
|
257
|
+
|
258
|
+
<!-- Categories Section -->
|
259
|
+
<div class="p-4">
|
260
|
+
{% include sidebar-categories.html %}
|
261
|
+
</div>
|
154
262
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
263
|
+
<!-- External Links Section -->
|
264
|
+
<div class="p-4">
|
265
|
+
<h4 class="fst-italic">Elsewhere</h4>
|
266
|
+
<ol class="list-unstyled">
|
267
|
+
<li><a href="#">GitHub</a></li>
|
268
|
+
<li><a href="#">Twitter</a></li>
|
269
|
+
<li><a href="#">Facebook</a></li>
|
270
|
+
</ol>
|
271
|
+
</div>
|
272
|
+
</div>
|
162
273
|
</div>
|
163
|
-
</div>
|
164
274
|
</div>
|
165
|
-
</div>
|
166
275
|
|
167
276
|
</main>
|
168
277
|
|
data/_layouts/collection.html
CHANGED
@@ -1,42 +1,123 @@
|
|
1
1
|
---
|
2
2
|
layout: default
|
3
3
|
---
|
4
|
-
<!--
|
4
|
+
<!--
|
5
|
+
===================================================================
|
6
|
+
COLLECTION LAYOUT - Display template for Jekyll collections
|
7
|
+
===================================================================
|
8
|
+
|
9
|
+
File: collection.html
|
10
|
+
Path: _layouts/collection.html
|
11
|
+
Inherits: default.html (which inherits root.html)
|
12
|
+
Purpose: Display collection pages with card-based grid layout
|
13
|
+
|
14
|
+
Template Logic:
|
15
|
+
- Displays individual collection items (like blog posts, projects, etc.)
|
16
|
+
- Creates responsive card grid using Bootstrap components
|
17
|
+
- Supports custom sorting and filtering of collection items
|
18
|
+
- Shows preview images with fallback to default teaser
|
19
|
+
- Implements semantic HTML5 structure for better SEO
|
20
|
+
|
21
|
+
Collection Configuration:
|
22
|
+
- Reads collection from page.collection frontmatter variable
|
23
|
+
- Sorts by page.sort_order (supports 'reverse' for descending)
|
24
|
+
- Falls back to default Jekyll collection ordering
|
25
|
+
|
26
|
+
Card Layout Features:
|
27
|
+
- Responsive grid (1 column mobile, up to 3 columns desktop)
|
28
|
+
- Equal height cards with Bootstrap h-100 class
|
29
|
+
- Preview images with fallback system
|
30
|
+
- Excerpt truncation for consistent appearance
|
31
|
+
- Last modified date in footer
|
32
|
+
|
33
|
+
SEO and Accessibility:
|
34
|
+
- Proper heading hierarchy with h2 for section title
|
35
|
+
- Microdata with itemprop attributes
|
36
|
+
- Alt text for images
|
37
|
+
- Semantic HTML structure
|
38
|
+
|
39
|
+
Dependencies:
|
40
|
+
- Jekyll collections system
|
41
|
+
- Bootstrap 5 card and grid components
|
42
|
+
- Site configuration for public_folder and teaser image
|
43
|
+
===================================================================
|
44
|
+
-->
|
45
|
+
|
46
|
+
<!-- ========================== -->
|
47
|
+
<!-- COLLECTION PAGE CONTENT -->
|
48
|
+
<!-- ========================== -->
|
49
|
+
<!-- Main content area for collection description or introduction -->
|
5
50
|
{{ content }}
|
6
51
|
|
52
|
+
<!-- ========================== -->
|
53
|
+
<!-- COLLECTION DATA PROCESSING -->
|
54
|
+
<!-- ========================== -->
|
55
|
+
<!-- Extract and sort collection entries based on page configuration -->
|
7
56
|
{% assign entries = site[page.collection] %}
|
8
57
|
{% assign entries = entries | sort: page.sort_order %}
|
58
|
+
|
59
|
+
<!-- Handle reverse sorting if specified -->
|
9
60
|
{% if page.sort_order == 'reverse' %}
|
10
|
-
{% assign entries = entries | reverse %}
|
61
|
+
{% assign entries = entries | reverse %}
|
11
62
|
{% endif %}
|
12
63
|
|
13
|
-
<!--
|
64
|
+
<!-- ========================== -->
|
65
|
+
<!-- COLLECTION INDEX HEADER -->
|
66
|
+
<!-- ========================== -->
|
14
67
|
<h2 id="index-collection">
|
15
|
-
|
68
|
+
Collection Index - {{ page.collection }}
|
16
69
|
</h2>
|
17
70
|
|
71
|
+
<!-- ================================ -->
|
72
|
+
<!-- COLLECTION ITEMS GRID -->
|
73
|
+
<!-- ================================ -->
|
74
|
+
<!-- Responsive card grid: 1 column mobile, up to 3 columns desktop -->
|
18
75
|
<div class="row row-cols-1 row-cols-md-3 g-4">
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
76
|
+
|
77
|
+
{% for post in entries %}
|
78
|
+
<div class="col">
|
79
|
+
<!-- Bootstrap card with equal height for consistent layout -->
|
80
|
+
<div class="card h-100">
|
81
|
+
|
82
|
+
<!-- ====================== -->
|
83
|
+
<!-- CARD IMAGE SECTION -->
|
84
|
+
<!-- ====================== -->
|
85
|
+
<!-- Display preview image with fallback to site teaser -->
|
86
|
+
{% if post.preview %}
|
87
|
+
<img src="{{site.baseurl}}/{{ site.public_folder }}/{{ post.preview}}"
|
88
|
+
class="card-img-top" alt="Preview image for {{ post.title }}">
|
89
|
+
{% else %}
|
90
|
+
<img src="{{site.baseurl}}/{{ site.public_folder }}/{{ site.teaser }}"
|
91
|
+
class="card-img-top" alt="Default preview image">
|
92
|
+
{% endif %}
|
93
|
+
|
94
|
+
<!-- ====================== -->
|
95
|
+
<!-- CARD CONTENT SECTION -->
|
96
|
+
<!-- ====================== -->
|
97
|
+
<div class="card-body">
|
98
|
+
<!-- Post title with SEO microdata -->
|
99
|
+
<h5 class="card-title" itemprop="headline">
|
100
|
+
<a class="card-link" href="{{ post.url | relative_url }}" rel="permalink">
|
101
|
+
{{ post.title }}
|
102
|
+
</a>
|
103
|
+
</h5>
|
104
|
+
|
105
|
+
<!-- Post excerpt with HTML stripped and character limit -->
|
106
|
+
<p class="card-text" itemprop="description">
|
107
|
+
{{ post.excerpt | strip_html | truncate: 160 }}
|
108
|
+
</p>
|
109
|
+
</div>
|
110
|
+
|
111
|
+
<!-- ====================== -->
|
112
|
+
<!-- CARD FOOTER SECTION -->
|
113
|
+
<!-- ====================== -->
|
114
|
+
<div class="card-footer">
|
115
|
+
<!-- Last modified date for content freshness indicator -->
|
116
|
+
<small class="text-body-secondary post-meta">
|
117
|
+
Last updated {{ post.lastmod | date: '%B %d, %Y' }}
|
118
|
+
</small>
|
119
|
+
</div>
|
120
|
+
</div>
|
121
|
+
</div>
|
122
|
+
{% endfor %}
|
42
123
|
</div>
|