+11
-2
src/content.config.ts
+11
-2
src/content.config.ts
···
7
7
schema: z.object({
8
8
title: z.string(),
9
9
description: z.string(),
10
-
year: z.number(),
11
-
published_at: z.date(),
10
+
publishedAt: z.union([z.date(), z.string()]).transform((val) => {
11
+
if (val instanceof Date) return val;
12
+
return new Date(val);
13
+
}),
14
+
publication: z.string().optional(),
15
+
author: z.string().optional(),
16
+
// Optional fields to match documents structure
17
+
rkey: z.string().optional(),
18
+
cid: z.string().optional(),
19
+
// Keep year for backward compatibility if needed
20
+
year: z.number().optional(),
12
21
}),
13
22
});
14
23
+1
-1
src/data/blog/building-a-ttc-alerts-bot-with-threads-api.mdx
+1
-1
src/data/blog/building-a-ttc-alerts-bot-with-threads-api.mdx
···
2
2
title: Building a TTC service alert bot with the Threads API and TTC Live Alerts API
3
3
description: Going into detail about how I built a bot to report service updates for the TTC on Threads
4
4
year: 2024
5
-
published_at: 2024-06-23
5
+
publishedAt: 2024-06-23
6
6
---
7
7
8
8
The Threads team at Meta finally released an API to interact with the Threads platform. I've had this idea of creating a bot account that posts updates about the TTC since the API was announced. I'm happy to announce that I've "finished" this project today. In this post I'll talk about how I built it and how I found and figured out how the TTC alerts API worked.
+1
-1
src/data/blog/docker-for-frontend-developers.mdx
+1
-1
src/data/blog/docker-for-frontend-developers.mdx
···
2
2
title: Docker for Frontend Developers
3
3
description: A short walkthrough on how to create an API
4
4
year: 2021
5
-
published_at: 2021-03-17
5
+
publishedAt: 2021-03-17
6
6
---
7
7
8
8
I'll be honest, it took me a while to understand what docker was and why/how one would even use it in a typical workflow. I've read the documentation months ago to understand the basics but never knew how I could apply it into my own workflow or projects until recently. That's when I started to use it wherever I could.
+1
-1
src/data/blog/give-angular-a-second-chance.mdx
+1
-1
src/data/blog/give-angular-a-second-chance.mdx
···
2
2
title: Why I think Developers should give Angular 17 a serious try
3
3
description: If you're a developer that is new to Angular and its ecosystem, you should definitely take a minute to try their latest release
4
4
year: 2023
5
-
published_at: 2023-12-15
5
+
publishedAt: 2023-12-15
6
6
---
7
7
8
8
You've seen the memes, you've seen the angry github comments, you've seen the negative press. I'll be honest, I fell victim to the propaganda online. Was some of it warranted? Probably, but some of it was a bit overexaggerated in my opinion. Seriously, Angular is a really good framework and I think the release of Angular 17 will bring it back into the light and a serious option for building websites. I've only been through the documentation briefly and did the tutorial but there are some things I _really_ like.
+2
-1
src/data/blog/running-a-containerized-application-in-the-cloud.mdx
+2
-1
src/data/blog/running-a-containerized-application-in-the-cloud.mdx
···
1
1
---
2
2
title: Running a containerized application in the cloud using AWS App Runner
3
3
description: Exploring the new AWS App Runner service
4
-
published_at: 2021-05-19
4
+
publishedAt: 2021-05-19
5
5
year: 2021
6
+
publication: t
6
7
---
7
8
8
9
I've been pretty deep in the cloud space for a few weeks now, researching different topics related to system design and playing around with different AWS services. So far I've been playing around with containers and figuring out ways I could deploy a simple containerized application to the cloud without much fuss. I've found AWS Elastic Container Service and AWS Elastic Kubernetes Service (more on kubernetes in another blog post, I've been having fun learning about it) but those are more for managing clusters of containers than just being able to deploy something simple and small. I've also looked at AWS Elastic Beanstalk and while it is possible to deploy docker containers through that service I haven't had much luck doing it through the UI or the Elastic Beanstalk CLI.
+1
-1
src/data/blog/supabase-auth-with-remix-and-vite.mdx
+1
-1
src/data/blog/supabase-auth-with-remix-and-vite.mdx
···
2
2
title: Add authentication to your Remix application with Supabase
3
3
description: Adding authentication to your remix app with Supabase has never been easier, this blog post will show you how to get up and running quickly
4
4
year: 2024
5
-
published_at: 2024-03-08
5
+
publishedAt: 2024-03-08
6
6
---
7
7
8
8
With Supabase now fully supporting doing authentication completely server-side, it has never been easier to take advantage of all of the features that it offers. We'll go through how to quickly spin up a Remix project and add supabase with authentication.
+1
-1
src/data/blog/type-safe-environment-variables-in-remix.mdx
+1
-1
src/data/blog/type-safe-environment-variables-in-remix.mdx
···
2
2
title: Type-safe environment variables in your Remix application using t3-env
3
3
description: Quickly and easily add type-safety and runtime validation to your environment variables using the t3-env package.
4
4
year: 2024
5
-
published_at: 2024-04-05
5
+
publishedAt: 2024-04-05
6
6
---
7
7
8
8
There are many was you can get type-safe variables in your projects, I've tried a few but recently found the t3-env package which makes it even easier and comes with some nice features as well. I will quickly walk through how to set this up in a Remix project.
+1
-1
src/data/blog/what-im-going-to-be-learning-in-2022.mdx
+1
-1
src/data/blog/what-im-going-to-be-learning-in-2022.mdx
+1
-1
src/data/blog/you-dont-have-to-code-all-the-time.mdx
+1
-1
src/data/blog/you-dont-have-to-code-all-the-time.mdx
+27
-10
src/pages/blogs/[blog].astro
+27
-10
src/pages/blogs/[blog].astro
···
1
1
---
2
2
import BlogLayout from "@layouts/BlogLayout.astro";
3
3
import { render } from "astro:content";
4
-
import { type CollectionEntry, getCollection, getEntry } from "astro:content";
4
+
import { getCollection, getEntry, type CollectionEntry } from "astro:content";
5
+
6
+
export const prerender = true;
5
7
6
8
export async function getStaticPaths() {
7
9
const documents = await getCollection("documents");
8
-
return documents.map((document) => ({
9
-
params: { blog: document.id },
10
-
props: document,
11
-
}));
10
+
const blogs = await getCollection("blogs");
11
+
12
+
// Combine both collections for static paths
13
+
const allPosts = [
14
+
...documents.map((document) => ({
15
+
params: { blog: document.id },
16
+
props: { collection: "documents" },
17
+
})),
18
+
...blogs.map((blog) => ({
19
+
params: { blog: blog.id },
20
+
props: { collection: "blogs" },
21
+
})),
22
+
];
23
+
24
+
return allPosts;
12
25
}
13
26
14
-
type Props = CollectionEntry<"documents">;
27
+
// Try to get the entry from both collections
28
+
let entry: CollectionEntry<"documents"> | CollectionEntry<"blogs"> | undefined =
29
+
await getEntry("documents", Astro.params.blog);
15
30
16
-
const document = await getEntry("documents", Astro.params.blog);
31
+
if (!entry) {
32
+
entry = await getEntry("blogs", Astro.params.blog);
33
+
}
17
34
18
-
if (!document) {
35
+
if (!entry) {
19
36
return Astro.rewrite("/404");
20
37
}
21
38
22
-
const { Content } = await render(document);
39
+
const { Content } = await render(entry);
23
40
---
24
41
25
42
<script>
···
49
66
});
50
67
</script>
51
68
52
-
<BlogLayout {...document!.data}>
69
+
<BlogLayout {...entry!.data}>
53
70
<Content />
54
71
</BlogLayout>
55
72
+25
-8
src/pages/blogs/index.astro
+25
-8
src/pages/blogs/index.astro
···
3
3
import BlogPost from "@components/BlogPost.astro";
4
4
import { getCollection } from "astro:content";
5
5
6
-
// const posts = (await getCollection("blogs")).sort(
7
-
// (a, b) => b.data.published_at.valueOf() - a.data.published_at.valueOf(),
8
-
// );
6
+
const blogs = await getCollection("blogs");
7
+
const documents = await getCollection("documents");
9
8
10
-
const documents = await getCollection("documents");
9
+
// Combine both collections and sort by publishedAt
10
+
const allPosts = [
11
+
...blogs.map((blog) => ({
12
+
...blog,
13
+
data: {
14
+
...blog.data,
15
+
// Ensure publishedAt is a Date object for consistent sorting
16
+
publishedAt: new Date(blog.data.publishedAt),
17
+
},
18
+
})),
19
+
...documents.map((document) => ({
20
+
...document,
21
+
data: {
22
+
...document.data,
23
+
// Ensure publishedAt is a Date object for consistent sorting
24
+
publishedAt: new Date(document.data.publishedAt),
25
+
},
26
+
})),
27
+
].sort((a, b) => b.data.publishedAt.valueOf() - a.data.publishedAt.valueOf());
11
28
---
12
29
13
30
<Layout
···
17
34
<h1 class="mt-4 mb-4 text-2xl font-bold text-snes-black">Blog</h1>
18
35
<ul class="space-y-4">
19
36
{
20
-
documents.map((document) => (
37
+
allPosts.map((post) => (
21
38
<BlogPost
22
-
title={document.data.title}
23
-
slug={document.id}
24
-
publishedAt={document.data.publishedAt}
39
+
title={post.data.title}
40
+
slug={post.id}
41
+
publishedAt={post.data.publishedAt.toISOString()}
25
42
/>
26
43
))
27
44
}
+26
-6
src/pages/index.astro
+26
-6
src/pages/index.astro
···
6
6
import { getCollection } from "astro:content";
7
7
const documents = await getCollection("documents");
8
8
const blogs = await getCollection("blogs");
9
+
10
+
// Combine both collections and sort by publishedAt
11
+
const allPosts = [
12
+
...blogs.map((blog) => ({
13
+
...blog,
14
+
data: {
15
+
...blog.data,
16
+
publishedAt: new Date(blog.data.publishedAt),
17
+
},
18
+
})),
19
+
...documents.map((document) => ({
20
+
...document,
21
+
data: {
22
+
...document.data,
23
+
publishedAt: new Date(document.data.publishedAt),
24
+
},
25
+
})),
26
+
]
27
+
.sort((a, b) => b.data.publishedAt.valueOf() - a.data.publishedAt.valueOf())
28
+
.slice(0, 5); // Show only the 5 most recent
9
29
---
10
30
11
31
<Layout
···
31
51
</div>
32
52
</div>
33
53
<div>
34
-
<h2 class="font-bold mb-1">Dane's latest blog entires</h2>
54
+
<h2 class="font-bold mb-1">Dane's latest blog entries</h2>
35
55
<ul>
36
56
{
37
-
documents.map((document) => (
57
+
allPosts.map((post) => (
38
58
<li class="mb-2">
39
59
<p class="mb-0 max-w-[60ch]">
40
-
{document.data.title}
60
+
{post.data.title}
41
61
<Link
42
-
href={`/blogs/${document.id}`}
62
+
href={`/blogs/${post.id}`}
43
63
extraClasses="text-sm font-bold ml-1"
44
64
>
45
65
(view more)
···
48
68
<span class="text-gray-500 text-sm">
49
69
posted on{" "}
50
70
<time
51
-
datetime={document.data.publishedAt}
71
+
datetime={post.data.publishedAt.toISOString()}
52
72
>
53
73
{new Intl.DateTimeFormat("en-US").format(
54
-
new Date(document.data.publishedAt),
74
+
post.data.publishedAt,
55
75
)}
56
76
</time>
57
77
</span>