Skip to content

Commit 75fbb0f

Browse files
JonathanMattheyAnca2022JoblersTune
authored
feat: add Tag filter to tech blog (#166)
* feat: add Tag filter to tech blog --------- Co-authored-by: Jon M <> Co-authored-by: Anca Matei <[email protected]> Co-authored-by: Sarah Jones <[email protected]>
1 parent bcb432c commit 75fbb0f

27 files changed

+538
-447
lines changed

README.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Source code for the /developer-tools portion of [Interledger.org](https://interl
66

77
Inside this project, you'll see the following folders and files:
88

9-
```
9+
```text
1010
.
1111
├── public/
1212
├── src/
@@ -98,6 +98,23 @@ If you're unsure how to structure your writing, you can use this as a guide.
9898

9999
Ideal Word Count: Between 1,000 and 2,500 words, with links to relevant documents/pages for a deeper understanding.
100100

101+
### Blog metadata and tags
102+
103+
Each blog post includes frontmatter at the top of the file (title, description, date, authors, etc.), including a `tags` field used for filtering on the blog index.
104+
105+
Please **only use the existing, approved tags** unless you have aligned with the tech + comms team on adding a new one. This helps keep the tag filter focused and avoids fragmentation.
106+
107+
**Current tags:**
108+
109+
- Interledger Protocol
110+
- Open Payments
111+
- Web Monetization
112+
- Rafiki
113+
- Updates
114+
- Releases
115+
116+
If you believe your post needs a new tag, propose it in your PR description or in the `#tech-team` Slack channel so we can decide whether to add it and update this list.
117+
101118
### Getting Started
102119

103120
Discuss Ideas: Before starting, share your blog post ideas with the tech team to ensure alignment and awareness.
Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
---
2+
import { createExcerpt } from '../../utils/create-excerpt'
3+
import TagFilter from './TagFilter.astro'
4+
import Pagination from './Pagination.astro'
5+
import type { CollectionEntry } from 'astro:content'
6+
7+
interface BreadcrumbItem {
8+
name: string
9+
href: string
10+
umamiEvent: string
11+
}
12+
13+
interface Props {
14+
title: string
15+
posts: CollectionEntry<'blog'>[]
16+
breadcrumbs?: BreadcrumbItem[]
17+
allTags?: string[]
18+
selectedTag?: string
19+
showTagFilter?: boolean
20+
showPagination?: boolean
21+
paginationProps?: {
22+
length: number
23+
currentPage: number
24+
firstUrl: string | undefined
25+
prevUrl: string | undefined
26+
nextUrl: string | undefined
27+
lastUrl: string | undefined
28+
}
29+
}
30+
31+
const {
32+
title,
33+
posts,
34+
breadcrumbs = [],
35+
allTags = [],
36+
selectedTag,
37+
showTagFilter = false,
38+
showPagination = false,
39+
paginationProps
40+
} = Astro.props
41+
---
42+
43+
<main>
44+
<div class="content-wrapper">
45+
{
46+
breadcrumbs.length > 0 && (
47+
<ol
48+
class="breadcrumbs"
49+
itemscope
50+
itemtype="https://schema.org/BreadcrumbList"
51+
>
52+
{breadcrumbs.map((crumb, index) => (
53+
<li
54+
itemprop="itemListElement"
55+
itemscope
56+
itemtype="https://schema.org/ListItem"
57+
>
58+
<a
59+
itemprop="item"
60+
href={crumb.href}
61+
data-umami-event={crumb.umamiEvent}
62+
>
63+
<span itemprop="name">{crumb.name}</span>
64+
</a>
65+
<meta itemprop="position" content={String(index + 1)} />
66+
</li>
67+
))}
68+
</ol>
69+
)
70+
}
71+
<header>
72+
<h1>{title}</h1>
73+
<a class="cta__blog" href="/blog">
74+
<p>Check out Foundation updates</p>
75+
<img
76+
src="/developers/img/ernie-purple.svg"
77+
alt="Ernie holding an envelope"
78+
aria-hidden="true"
79+
/>
80+
</a>
81+
</header>
82+
{showTagFilter && <TagFilter allTags={allTags} selectedTag={selectedTag} />}
83+
<ol class="postlist">
84+
{
85+
posts.map((blogPostEntry) => {
86+
const excerpt = `${createExcerpt(blogPostEntry.body).substring(0, 300)}...`
87+
return (
88+
<li class="postlist-item">
89+
<time
90+
class="postlist-date"
91+
datetime={blogPostEntry.data.date.toISOString()}
92+
>
93+
{blogPostEntry.data.date.toDateString()}
94+
</time>
95+
{blogPostEntry.data.lang ? (
96+
<div class="postlist-es">
97+
<a
98+
href={`/developers/blog/${blogPostEntry.id}`}
99+
class="postlist-link heading--6"
100+
>
101+
{blogPostEntry.data.title}
102+
</a>
103+
<a class="postlist-lang" href="/developers/blog/es">
104+
ES
105+
</a>
106+
</div>
107+
) : (
108+
<a
109+
href={`/developers/blog/${blogPostEntry.id}`}
110+
class="postlist-link heading--6"
111+
>
112+
{blogPostEntry.data.title}
113+
</a>
114+
)}
115+
<p>
116+
{blogPostEntry.data.description
117+
? blogPostEntry.data.description
118+
: excerpt}
119+
</p>
120+
</li>
121+
)
122+
})
123+
}
124+
</ol>
125+
{
126+
showPagination && paginationProps && (
127+
<Pagination
128+
length={paginationProps.length}
129+
currentPage={paginationProps.currentPage}
130+
firstUrl={paginationProps.firstUrl}
131+
prevUrl={paginationProps.prevUrl}
132+
nextUrl={paginationProps.nextUrl}
133+
lastUrl={paginationProps.lastUrl}
134+
/>
135+
)
136+
}
137+
</div>
138+
</main>
139+
140+
<style>
141+
main {
142+
padding-block-start: var(--space-m);
143+
padding-block-end: var(--space-xl);
144+
}
145+
146+
.breadcrumbs {
147+
list-style: none;
148+
display: flex;
149+
padding-inline-start: 0;
150+
font-size: var(--step--1);
151+
font-weight: 700;
152+
padding-block-start: var(--space-l);
153+
}
154+
155+
.breadcrumbs li:not(:first-child)::before {
156+
content: '>';
157+
display: inline-flex;
158+
margin-inline-start: var(--space-3xs);
159+
}
160+
161+
.breadcrumbs a {
162+
color: var(--color-primary);
163+
text-decoration: none;
164+
}
165+
166+
ol {
167+
padding: 0;
168+
}
169+
170+
header {
171+
padding-block-start: var(--space-s);
172+
padding-block-end: var(--space-m);
173+
display: flex;
174+
justify-content: space-between;
175+
align-items: center;
176+
gap: var(--space-xs);
177+
}
178+
179+
@media screen and (max-width: 730px) {
180+
header {
181+
flex-direction: column;
182+
align-items: start;
183+
}
184+
}
185+
186+
.cta__blog {
187+
display: flex;
188+
align-items: center;
189+
gap: var(--space-s);
190+
padding: var(--space-3xs) var(--space-2xs);
191+
background-color: white;
192+
box-shadow: var(--box-shadow);
193+
border-radius: var(--border-radius);
194+
font-size: var(--step--1);
195+
background-image: var(--color-white);
196+
text-decoration: none;
197+
}
198+
199+
.cta__blog p {
200+
flex: none;
201+
text-decoration-color: transparent;
202+
text-decoration-line: underline;
203+
transition: text-decoration-color 300ms ease-in-out;
204+
}
205+
206+
.cta__blog:hover {
207+
color: inherit;
208+
}
209+
210+
.cta__blog:hover p {
211+
color: currentColor;
212+
text-decoration-color: currentColor;
213+
}
214+
215+
.cta__blog img {
216+
width: 4em;
217+
}
218+
219+
.post-metadata,
220+
.links-nextprev,
221+
.postlist {
222+
list-style: none;
223+
}
224+
225+
.postlist-item {
226+
display: flex;
227+
flex-direction: column;
228+
margin-bottom: var(--space-s);
229+
}
230+
231+
.postlist-date {
232+
font-size: var(--step--1);
233+
}
234+
235+
.postlist-link {
236+
font-weight: 600;
237+
text-decoration-color: transparent;
238+
transition:
239+
text-decoration 300ms ease-in-out,
240+
color 300ms ease-in-out;
241+
}
242+
243+
.postlist-link:hover {
244+
text-decoration-color: currentColor;
245+
}
246+
247+
.postlist-es {
248+
display: flex;
249+
align-items: start;
250+
gap: var(--space-2xs);
251+
}
252+
253+
.postlist-lang {
254+
border: 1.5px solid;
255+
padding-inline: 4px;
256+
border-radius: var(--border-radius);
257+
font-size: var(--step--1);
258+
background-color: white;
259+
margin-block-start: var(--space-3xs);
260+
text-decoration: none;
261+
}
262+
</style>
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
---
2+
import { getTagUrl } from '../../utils/tag-url'
3+
4+
interface Props {
5+
allTags: string[]
6+
selectedTag?: string
7+
}
8+
9+
const { allTags, selectedTag } = Astro.props
10+
---
11+
12+
<div class="tag-filter">
13+
<div class="tag-filter-label">Filter by tag:</div>
14+
<div class="tag-filter-buttons">
15+
<a
16+
href="/developers/blog"
17+
class:list={['tag-button', { active: !selectedTag }]}
18+
data-umami-event="Blog tag filter - All"
19+
>
20+
All
21+
</a>
22+
{
23+
allTags.map((tag) => (
24+
<a
25+
href={getTagUrl(tag)}
26+
class:list={['tag-button', { active: selectedTag === tag }]}
27+
data-umami-event={`Blog tag filter - ${tag}`}
28+
>
29+
{tag}
30+
</a>
31+
))
32+
}
33+
</div>
34+
</div>
35+
36+
<style>
37+
.tag-filter {
38+
margin-block-end: var(--space-m);
39+
background-color: var(--color-background-light);
40+
border-radius: var(--border-radius);
41+
}
42+
43+
.tag-filter-label {
44+
font-weight: 600;
45+
margin-block-end: var(--space-3xs);
46+
font-size: var(--step--1);
47+
}
48+
49+
.tag-filter-buttons {
50+
display: flex;
51+
flex-wrap: wrap;
52+
gap: var(--space-3xs);
53+
}
54+
55+
.tag-button {
56+
padding: var(--space-3xs) var(--space-2xs);
57+
background-color: white;
58+
border: 1.5px solid var(--color-border);
59+
border-radius: var(--border-radius);
60+
font-size: var(--step--1);
61+
text-decoration: none;
62+
color: var(--color-text);
63+
box-shadow: var(--box-shadow);
64+
transition:
65+
background-color 200ms ease-in-out,
66+
color 200ms ease-in-out,
67+
border-color 200ms ease-in-out,
68+
text-decoration 200ms ease-in-out;
69+
}
70+
71+
.tag-button:hover {
72+
background-color: white;
73+
border-color: var(--color-primary);
74+
color: var(--color-text);
75+
text-decoration: underline;
76+
}
77+
78+
.tag-button.active {
79+
background-color: var(--color-primary);
80+
color: white;
81+
border-color: var(--color-primary);
82+
}
83+
</style>

src/content/blog/2018-01-29-simplifying-interledger-the-graveyard-of-possible-protocol-features.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ author_urls:
99
- https://www.linkedin.com/in/evanmarkschwartz/
1010
external_url: https://medium.com/interledger-blog/simplifying-interledger-the-graveyard-of-possible-protocol-features-b35bf67439be
1111
tags:
12-
- Interledger
13-
- Interoperability
12+
- Interledger Protocol
1413
---
1514

1615
As the development of the [Interledger Protocol](https://interledger.org/) (ILP) nears completion, I thought we should take a moment to remember some of the many core protocol features we’ve killed off along the way.

0 commit comments

Comments
 (0)