Skip to content

Commit 0d4f4fa

Browse files
authored
Update blog section with category filter and improved styling
1 parent 27953da commit 0d4f4fa

File tree

4 files changed

+186
-47
lines changed

4 files changed

+186
-47
lines changed

content/blog/_index.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
+++
22
title = "Blog"
33
description = "This is an ongoing series of articles about <b>idiomatic Rust</b> and <b>best practices</b>.<br /> Sign up to my newsletter below to be notified when I publish new articles."
4-
sort_by = "date"
4+
sort_by = "update_date"
5+
paginate_reversed = true
56
insert_anchor_links = "heading"
67
+++

sass/_article.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ article .subheading a {
157157
}
158158

159159
.article-content {
160-
padding: 0 1em;
160+
padding: 0;
161161
}
162162

163163
.info {

sass/_blog.scss

Lines changed: 125 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,169 @@
11
.blog-list {
22
list-style: none;
33
padding: 0;
4-
width: 43rem;
54
}
65

7-
.blog-list .blog-item {
8-
border-bottom: 1px solid rgba($brightPrim, 0.1);
6+
.blog-item {
7+
border-bottom: 1px solid rgba($brightPrim, 0.08);
8+
99
&:last-child {
1010
border-bottom: none;
1111
}
12+
13+
&:hover {
14+
background-color: rgba($brightBgrd, 0.15);
15+
16+
.blog-chevron {
17+
opacity: 1;
18+
transform: translateX(0) rotate(270deg);
19+
}
20+
}
1221
}
1322

1423
.blog-link {
15-
padding: 10px 0;
16-
display: flex;
24+
padding: 1.5rem 0;
25+
display: grid;
26+
grid-template-columns: auto 1fr auto;
27+
gap: 1.5rem;
1728
align-items: center;
1829
text-decoration: none;
1930
color: inherit;
2031
}
2132

2233
.blog-date {
2334
font-family: monospace;
24-
font-size: 0.8em;
35+
font-size: 0.85rem;
2536
color: rgba($brightPrim, 0.6);
26-
min-width: 100px;
27-
flex-shrink: 0;
37+
font-weight: 500;
38+
white-space: nowrap;
39+
}
40+
41+
.blog-content {
42+
display: flex;
43+
flex-direction: column;
44+
gap: 0.25rem;
2845
}
2946

3047
.blog-title {
3148
font-family: "Inter", Arial, sans-serif;
32-
font-weight: 400;
33-
font-size: 1em;
49+
font-weight: 600;
50+
font-size: 1.1rem;
3451
color: $brightPrim;
35-
flex: 1;
36-
margin: 0 1rem;
52+
margin: 0;
53+
line-height: 1.3;
54+
}
55+
56+
.blog-category {
57+
font-size: 0.8rem;
58+
color: rgba($brightPrim, 0.5);
59+
font-weight: 500;
60+
text-transform: uppercase;
61+
letter-spacing: 0.05em;
3762
}
3863

39-
.blog-item:hover {
40-
background-color: rgba($brightBgrdLight, 0.3);
64+
.blog-chevron {
65+
@extend .chevron;
66+
transform: translateX(-20px) rotate(270deg);
67+
opacity: 0;
68+
transition: all 0.3s ease;
69+
margin-right: 1rem;
70+
}
71+
72+
.blog-filters {
73+
margin-bottom: 2.5rem;
74+
display: flex;
75+
justify-content: flex-end;
76+
align-items: center;
77+
gap: 0.75rem;
78+
79+
label {
80+
font-weight: 500;
81+
font-size: 0.9rem;
82+
}
83+
84+
select {
85+
padding: 0.6rem 1rem;
86+
border: 1px solid rgba($heroDark, 0.3);
87+
border-radius: 6px;
88+
background-color: white;
89+
font-size: 0.9rem;
90+
cursor: pointer;
91+
transition: border-color 0.2s ease;
92+
93+
&:hover {
94+
border-color: rgba($heroDark, 0.5);
95+
}
96+
97+
&:focus {
98+
outline: none;
99+
border-color: $brightScnd;
100+
box-shadow: 0 0 0 2px rgba($brightScnd, 0.1);
101+
}
102+
}
41103
}
42104

43-
@media (max-width: 650px) {
44-
.blog-list {
45-
// Full width on smaller screens
46-
max-width: 100%;
105+
@media (max-width: 768px) {
106+
.blog-filters {
107+
justify-content: center;
108+
margin-bottom: 2rem;
109+
padding: 0 1rem;
110+
}
111+
112+
.blog-link {
113+
grid-template-columns: 1fr;
114+
gap: 0.75rem;
115+
padding: 1.25rem 1rem;
116+
}
117+
118+
.blog-date {
119+
font-size: 0.8rem;
120+
order: 2;
121+
}
122+
123+
.blog-content {
124+
order: 1;
125+
}
126+
127+
.blog-chevron {
128+
display: none;
47129
}
48130
}
49131

50132
// Dark mode
51133
@media (prefers-color-scheme: dark) {
52134
.blog-item {
53-
border-bottom: 1px solid rgba(white, 0.2);
54-
}
135+
border-bottom-color: rgba(white, 0.1);
55136

56-
.blog-item:hover {
57-
background-color: $darkBgrd;
137+
&:hover {
138+
background-color: rgba($brightBgrd, 0.1);
139+
}
58140
}
59141

60142
.blog-date {
61-
color: $darkPrim;
143+
color: rgba(white, 0.6);
62144
}
63145

64146
.blog-title {
65147
color: white;
66148
}
149+
150+
.blog-category {
151+
color: rgba(white, 0.5);
152+
}
153+
154+
.blog-filters select {
155+
background-color: $heroDark;
156+
color: white;
157+
border-color: rgba(white, 0.2);
158+
159+
&:hover {
160+
border-color: rgba(white, 0.4);
161+
}
162+
163+
&:focus {
164+
border-color: $brightBgrd;
165+
box-shadow: 0 0 0 2px rgba($brightBgrd, 0.1);
166+
}
167+
}
168+
67169
}

templates/section.html

Lines changed: 58 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,61 @@
11
{% extends "base.html" %} {% block content %}
2-
<article class="section-wrapper">
3-
<h1>{{section.title}}</h1>
4-
{{ section.description | safe }}
5-
<div>{{ section.content | safe }}</div>
6-
{% set sorted_pages = section.pages | filter(attribute="draft", value=false) |
7-
sort(attribute="extra.series") %} {% for series, series_pages in sorted_pages
8-
| group_by(attribute="extra.series") %}
9-
<h2>{{ series }}</h2>
10-
<ul class="blog-list">
11-
{% for page in series_pages %}
12-
<li class="blog-item">
13-
<a href="{{ page.permalink }}" class="blog-link">
14-
<time class="blog-date" datetime="{{ page.date }}"
15-
>{{ page.date }}</time
16-
>
17-
<h3 class="blog-title">{{ page.title }}</h3>
18-
<span class="chevron" aria-hidden="true"></span>
19-
</a>
20-
</li>
21-
{% endfor %}
22-
</ul>
23-
{% endfor %} {% include "snippets/newsletter.html" %}
2+
<article>
3+
<div class="article-heading">
4+
<h1>{{section.title}}</h1>
5+
{{ section.description | safe }}
6+
<div>{{ section.content | safe }}</div>
7+
</div>
8+
9+
<div class="article-content-wrapper">
10+
<div class="article-content">
11+
<div class="blog-filters">
12+
<label for="category-filter">Filter by category:</label>
13+
<select id="category-filter">
14+
<option value="all">All Posts</option>
15+
<option value="idiomatic-rust">Idiomatic Rust</option>
16+
<option value="rust-insights">Rust Insights</option>
17+
</select>
18+
</div>
19+
20+
{% set all_posts = section.pages | filter(attribute="draft", value=false) %}
21+
<ul class="blog-list" id="blog-list">
22+
{% for post in all_posts %}
23+
<li class="blog-item" data-category="{{ post.extra.series | lower | replace(from=" ", to="-") }}">
24+
<a href="{{ post.permalink }}" class="blog-link">
25+
<time class="blog-date" datetime="{% if post.updated %}{{ post.updated }}{% else %}{{ post.date }}{% endif %}">{% if post.updated %}{{ post.updated }}{% else %}{{ post.date }}{% endif %}</time>
26+
<div class="blog-content">
27+
<h3 class="blog-title">{{ post.title }}</h3>
28+
<span class="blog-category">{{ post.extra.series }}</span>
29+
</div>
30+
<span class="blog-chevron" aria-hidden="true"></span>
31+
</a>
32+
</li>
33+
{% endfor %}
34+
</ul>
35+
36+
{% include "snippets/newsletter.html" %}
37+
</div>
38+
</div>
2439
</article>
40+
41+
<script>
42+
document.addEventListener('DOMContentLoaded', function() {
43+
const categoryFilter = document.getElementById('category-filter');
44+
const blogItems = document.querySelectorAll('.blog-item');
45+
46+
function filterPosts() {
47+
const selectedCategory = categoryFilter.value;
48+
49+
blogItems.forEach(item => {
50+
if (selectedCategory === 'all' || item.dataset.category === selectedCategory) {
51+
item.style.display = 'block';
52+
} else {
53+
item.style.display = 'none';
54+
}
55+
});
56+
}
57+
58+
categoryFilter.addEventListener('change', filterPosts);
59+
});
60+
</script>
2561
{% endblock content %}

0 commit comments

Comments
 (0)