tangled
alpha
login
or
join now
aylac.top
/
mysite
0
fork
atom
my personal website!
0
fork
atom
overview
issues
2
pulls
pipelines
blog thing
aylac.top
11 months ago
0097fb58
1db23a12
verified
This commit was signed with the committer's
known signature
.
aylac.top
SSH Key Fingerprint:
SHA256:0I0RwJANCpgZd/yP0LOSXWEd0lfj1yyKsKISzeJAJ78=
+153
-18
8 changed files
expand all
collapse all
unified
split
_data
blogEntries.js
_includes
main_layout.njk
blog-entry.njk
blog-index.njk
eleventy.config.js
package.json
pnpm-lock.yaml
styles.scss
+30
_data/blogEntries.js
···
1
1
+
import { XRPC, CredentialManager } from "@atcute/client";
2
2
+
3
3
+
const manager = new CredentialManager({
4
4
+
service: "https://inkcap.us-east.host.bsky.network",
5
5
+
});
6
6
+
const rpc = new XRPC({ handler: manager });
7
7
+
8
8
+
let records = [];
9
9
+
let cursor = undefined;
10
10
+
do {
11
11
+
const response = (
12
12
+
await rpc.get("com.atproto.repo.listRecords", {
13
13
+
params: {
14
14
+
repo: "did:plc:avlpu4l2j5u3johint7tqrmu",
15
15
+
collection: "top.aylac.blog.entry",
16
16
+
cursor: cursor,
17
17
+
limit: 100,
18
18
+
},
19
19
+
})
20
20
+
).data;
21
21
+
records = records.concat(response.records);
22
22
+
cursor = response.cursor;
23
23
+
} while (cursor);
24
24
+
records.sort(
25
25
+
(a, b) => new Date(b.value.createdAt) - new Date(a.value.createdAt),
26
26
+
);
27
27
+
28
28
+
export default function () {
29
29
+
return records;
30
30
+
}
+3
-2
_includes/main_layout.njk
···
3
3
<head>
4
4
<meta charset="utf-8" />
5
5
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
-
<link rel="stylesheet" href="./styles.css" />
6
6
+
<link rel="stylesheet" href="/styles.css" />
7
7
<link rel="icon" href="./favicon.png" />
8
8
<title>{{ title }}</title>
9
9
</head>
10
10
<body>
11
11
-
{{ content | safe }}
11
11
+
<div class="nav"><a href="/">home</a><span>ayla</span><a href="/blog">blog</a></div>
12
12
+
{{ content | safe }}
12
13
</body>
13
14
</html>
+17
blog-entry.njk
···
1
1
+
---
2
2
+
layout: main_layout.njk
3
3
+
pagination:
4
4
+
data: blogEntries
5
5
+
size: 1
6
6
+
alias: blog
7
7
+
addAllPagesToCollections: true
8
8
+
permalink: "/blog/{{ blog.value.title | slugify }}/index.html"
9
9
+
eleventyComputed:
10
10
+
title: "{{ blog.value.title }} - ayla"
11
11
+
---
12
12
+
13
13
+
<div class="header">
14
14
+
<h1>{{ blog.value.title }}</h1>
15
15
+
<span class="date">{{ blog.value.createdAt | format_date }}</span>
16
16
+
</div>
17
17
+
{{ blog.value.content | markdown | safe }}
+13
blog-index.njk
···
1
1
+
---
2
2
+
layout: main_layout.njk
3
3
+
permalink: "/blog/index.html"
4
4
+
title: "blog - ayla"
5
5
+
---
6
6
+
7
7
+
{% for entry in blogEntries %}
8
8
+
<div class="entry">
9
9
+
<a class="entry-title" href="/blog/{{ entry.value.title | slugify }}">{{ entry.value.title }}</a>
10
10
+
<span class="entry-excerpt">{{ entry.value.content | truncate }}</span>
11
11
+
<span class="entry-date">{{ entry.value.createdAt | format_date }}</span>
12
12
+
</div>
13
13
+
{% endfor %}
+19
-7
eleventy.config.js
···
1
1
-
module.exports = function (eleventyConfig) {
2
2
-
const htmlmin = require("html-minifier");
3
3
-
const sass = require("sass");
4
4
-
const path = require("path");
1
1
+
import htmlmin from "html-minifier";
2
2
+
import * as sass from "sass";
3
3
+
import path from "path";
4
4
+
import markdownit from "markdown-it";
5
5
+
const md = markdownit();
5
6
7
7
+
export default function (eleventyConfig) {
6
8
eleventyConfig.addPassthroughCopy("favicon.png");
7
7
-
eleventyConfig.addPassthroughCopy("_config.yml");
8
8
-
eleventyConfig.addPassthroughCopy("CNAME");
9
9
eleventyConfig.addPassthroughCopy(".well-known/*");
10
10
11
11
eleventyConfig.addTemplateFormats("scss");
···
33
33
}
34
34
return content;
35
35
});
36
36
-
};
36
36
+
37
37
+
eleventyConfig.addNunjucksFilter("markdown", function (value) {
38
38
+
return md.render(value);
39
39
+
});
40
40
+
41
41
+
eleventyConfig.addNunjucksFilter("format_date", function (value) {
42
42
+
return new Date(value).toISOString().slice(0, 16).replace("T", " ");
43
43
+
});
44
44
+
45
45
+
eleventyConfig.addNunjucksFilter("truncate", function (value, length = 300) {
46
46
+
return value.slice(0, length);
47
47
+
});
48
48
+
}
+10
-5
package.json
···
1
1
{
2
2
-
"devDependencies": {
3
3
-
"@11ty/eleventy": "^3.0.0",
4
4
-
"html-minifier": "^4.0.0",
5
5
-
"sass": "^1.85.1"
6
6
-
}
2
2
+
"type": "module",
3
3
+
"devDependencies": {
4
4
+
"@11ty/eleventy": "^3.0.0",
5
5
+
"html-minifier": "^4.0.0",
6
6
+
"markdown-it": "^14.1.0",
7
7
+
"sass": "^1.85.1"
8
8
+
},
9
9
+
"dependencies": {
10
10
+
"@atcute/client": "^2.0.9"
11
11
+
}
7
12
}
+12
pnpm-lock.yaml
···
7
7
importers:
8
8
9
9
.:
10
10
+
dependencies:
11
11
+
'@atcute/client':
12
12
+
specifier: ^2.0.9
13
13
+
version: 2.0.9
10
14
devDependencies:
11
15
'@11ty/eleventy':
12
16
specifier: ^3.0.0
···
14
18
html-minifier:
15
19
specifier: ^4.0.0
16
20
version: 4.0.0
21
21
+
markdown-it:
22
22
+
specifier: ^14.1.0
23
23
+
version: 14.1.0
17
24
sass:
18
25
specifier: ^1.85.1
19
26
version: 1.85.1
···
58
65
59
66
'@11ty/recursive-copy@3.0.1':
60
67
resolution: {integrity: sha512-suoSv7CanyKXIwwtLlzP43n3Mm3MTR7UzaLgnG+JP9wAdg4uCIUJiAhhgs/nkwtkvsuqfrGWrUiaG1K9mEoiPg==}
68
68
+
69
69
+
'@atcute/client@2.0.9':
70
70
+
resolution: {integrity: sha512-QNDm9gMP6x9LY77ArwY+urQOBtQW74/onEAz42c40JxRm6Rl9K9cU4ROvNKJ+5cpVmEm1sthEWVRmDr5CSZENA==}
61
71
62
72
'@isaacs/cliui@8.0.2':
63
73
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
···
995
1005
promise: 7.3.1
996
1006
rimraf: 5.0.10
997
1007
slash: 1.0.0
1008
1008
+
1009
1009
+
'@atcute/client@2.0.9': {}
998
1010
999
1011
'@isaacs/cliui@8.0.2':
1000
1012
dependencies:
+49
-4
styles.scss
···
14
14
padding: 8px;
15
15
}
16
16
17
17
-
ul p {
18
18
-
margin: 0;
19
19
-
}
20
20
-
21
17
.mono {
22
18
font-family: "JetBrains Mono", monospace;
23
19
word-wrap: break-word;
24
20
}
25
21
22
22
+
.nav {
23
23
+
display: flex;
24
24
+
justify-content: space-around;
25
25
+
align-items: center;
26
26
+
margin-bottom: 8px;
27
27
+
font-weight: 600;
28
28
+
span {
29
29
+
font-weight: 800;
30
30
+
}
31
31
+
}
32
32
+
33
33
+
.header {
34
34
+
margin-top: 0;
35
35
+
padding-bottom: 14px;
36
36
+
margin-bottom: 14px;
37
37
+
border-bottom: 1px dashed rgba(255, 255, 255, 0.25);
38
38
+
h1 {
39
39
+
font-size: 28px;
40
40
+
margin: 0;
41
41
+
}
42
42
+
.date {
43
43
+
font-size: 12px;
44
44
+
font-weight: 600;
45
45
+
opacity: 0.9;
46
46
+
}
47
47
+
}
48
48
+
26
49
h1 {
27
50
font-weight: 800;
28
51
font-size: 20px;
···
59
82
color: black;
60
83
}
61
84
85
85
+
.entry {
86
86
+
display: flex;
87
87
+
flex-direction: column;
88
88
+
gap: 8px;
89
89
+
margin-bottom: 16px;
90
90
+
}
91
91
+
.entry-title {
92
92
+
font-size: 28px;
93
93
+
font-weight: 800;
94
94
+
}
95
95
+
.entry-excerpt {
96
96
+
font-size: 16px;
97
97
+
opacity: 0.9;
98
98
+
}
99
99
+
.entry-date {
100
100
+
font-size: 12px;
101
101
+
font-weight: 600;
102
102
+
}
103
103
+
62
104
@media (prefers-color-scheme: light) {
63
105
body {
64
106
background: white;
···
66
108
}
67
109
::selection {
68
110
color: white;
111
111
+
}
112
112
+
.header {
113
113
+
border-bottom: 1px dashed rgba(0, 0, 0, 0.25);
69
114
}
70
115
}
71
116