Skip to content

Commit

Permalink
combine existing blog with UW-UPL/harvest post aggregator
Browse files Browse the repository at this point in the history
  • Loading branch information
nicosalm committed Feb 6, 2025
1 parent a69bcc7 commit 281dd26
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 51 deletions.
7 changes: 7 additions & 0 deletions .astro/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,13 @@ declare module 'astro:content' {
collection: "coordinators";
data: InferEntrySchema<"coordinators">
};
};
"harvest": {
".github/workflows/update": {
id: ".github/workflows/update";
collection: "harvest";
data: any
};
};

};
Expand Down
6 changes: 5 additions & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,8 @@
url = https://github.com/UW-UPL/resources.git
[submodule "src/content/docs"]
path = src/content/docs
url = https://github.com/UW-UPL/Documentation
url = https://github.com/UW-UPL/Documentation
[submodule "src/content/harvest"]
path = src/content/harvest
url = https://github.com/UW-UPL/harvest.git

48 changes: 31 additions & 17 deletions src/components/BlogPostCard.astro
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
---
import type { CollectionEntry } from "astro:content";
type Props = CollectionEntry<"blog">;
type Props = {
collection: string;
data: {
title: string;
pubDate: Date;
author: string;
description?: string;
sourceUrl?: string;
};
slug?: string;
render?: () => Promise<any>;
};
const { data, render, slug } = Astro.props;
const { data, collection, render, slug } = Astro.props;
let formatter = new Intl.DateTimeFormat("en", {
year: "numeric",
Expand All @@ -12,23 +23,26 @@ let formatter = new Intl.DateTimeFormat("en", {
});
const formattedPubDate = formatter.format(data.pubDate);
const formattedUpdatedDate = formatter.format(data.updatedDate);
const readingTime = (await render()).remarkPluginFrontmatter.minutesRead;
const href = collection === "harvest" ? data.sourceUrl : `/blog/${slug}/`;
---

<a
href={`/blog/${slug}/`}
class="flex flex-col bg-red-100 p-6 rounded-lg drop-shadow-xl text-neutral-800 font-sans"
href={href}
class="block w-full bg-red-100 rounded-lg hover:shadow-lg transition-shadow duration-200"
target={collection === "harvest" ? "_blank" : "_self"}
rel={collection === "harvest" ? "noopener noreferrer" : null}
>
<h1 class="lg:text-xl text-lg font-semibold">
{data.title}
</h1>
<h6 class="font-medium text-xs">
Published {formattedPubDate}{
data.updatedDate && ` · Edited ${formattedUpdatedDate}`
} · {readingTime} · By {data.author}
</h6>
<p class="text-md font-normal mt-2 text-sm">{data.description}</p>
<div class="p-6">
<h1 class="text-xl font-bold text-gray-900 mb-2">
{data.title}
</h1>
<div class="text-sm text-gray-600 mb-3">
Published {formattedPubDate} · By {data.author}
</div>
{data.description &&
<p class="text-gray-700 line-clamp-3">
{data.description}
</p>
}
</div>
</a>
10 changes: 9 additions & 1 deletion src/content/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ const blog = defineCollection({
}),
});

const harvest = defineCollection({
type: "content",
// Minimal schema since we're dealing with a single markdown file
schema: z.object({
title: z.string().optional(),
}),
});

const events = defineCollection({
type: "content",
schema: z.object({
Expand Down Expand Up @@ -61,4 +69,4 @@ const resources = defineCollection({
}),
});

export const collections = { blog, events, resources, coordinators };
export const collections = { blog, harvest, events, resources, coordinators };
11 changes: 11 additions & 0 deletions src/content/events/lightning-talks-spring-2025-1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
title: "UPL Lightning Talks ⚡"
date: 2025-02-21 5:30 PM
location: 1240 Computer Sciences (CS Auditorium)
---

Ready to learn something new? UPLers share knowledge about their favorite topics in tech. Come to our Lightning Talks.

You can watch the videos from past talks [here](https://www.youtube.com/playlist?list=PLtu1Btc5X0_mj-pEoJk-aQCUziIDAA7Xn)!


1 change: 1 addition & 0 deletions src/content/harvest
Submodule harvest added at 66c8ed
123 changes: 91 additions & 32 deletions src/pages/blog/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,104 @@ import { getCollection } from "astro:content";
import Layout from "../../layouts/Layout.astro";
import BlogPostCard from "../../components/BlogPostCard.astro";
// get all blog posts, sort by publish date
const posts = (await getCollection("blog")).sort(
(a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf()
// Get regular blog posts
const blogPosts = (await getCollection("blog")).map(post => ({
...post,
collection: "blog"
}));
// Get harvested posts
const harvestPosts = await getCollection("harvest");
const blogPostsFile = harvestPosts.find(file => file.id === 'output/blog_posts.md');
const harvestedContent = blogPostsFile?.body || "";
// Parse the harvested posts
const harvestedPosts = harvestedContent
.split("\n---\n")
.map(section => section.trim())
.filter(section => section && !section.startsWith("# UPL Blog Posts"))
.map(section => {
// Ensure we're working with clean lines
const lines = section.split("\n").filter(line => line.trim());
const titleMatch = lines[0].match(/## \[(.*?)\]\((.*?)\)/);
const authorMatch = lines[1].match(/\*By (.*?) on (.*?)\*/);
if (!titleMatch || !authorMatch) {
console.log("Failed to parse section:", section); // Debug log
return null;
}
return {
collection: "harvest",
data: {
title: titleMatch[1],
sourceUrl: titleMatch[2],
author: authorMatch[1],
pubDate: new Date(authorMatch[2]),
description: lines.slice(2).join("\n").trim(),
}
};
})
.filter(post => post !== null);
// Create a Set of existing blog titles for deduplication
const existingTitles = new Set(blogPosts.map(post => post.data.title.toLowerCase()));
// Filter out harvested posts that already exist in blog posts
const uniqueHarvestedPosts = harvestedPosts.filter(
post => !existingTitles.has(post.data.title.toLowerCase())
);
// Combine and sort all posts
const posts = [...blogPosts, ...uniqueHarvestedPosts].sort(
(a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf()
);
const formatter = new Intl.DateTimeFormat("en-US", {
month: "long",
year: "numeric",
month: "long",
year: "numeric",
});
// as we build the list of posts, we need to track the month-year of each one so we don't duplicate month-year headers
let previousMonthYear = "";
---

<Layout>
<h1 class="text-4xl font-semibold font-lato text-center pb-2">Blog</h1>
<p class="font-sans lg:text-lg text-md text-gray-600 font-light pb-14 text-center">
Ramblings from coords and other friends. Learn something new
about technology, and maybe even yourself.
</p>
{
posts.map((post) => {
let monthYear = null;
const currMonthYear = formatter.format(post.data.pubDate);
if (currMonthYear !== previousMonthYear) {
monthYear = (
<h2 class="md:text-3xl text-xl text-gray-600 font-bold md:mt-6 md:mb-9 mb-3 pl-1">
{currMonthYear}
</h2>
);
previousMonthYear = currMonthYear;
}

return (
<div class="mt-14">
{monthYear}
<BlogPostCard {...post} />
</div>
);
})
}
<div class="max-w-4xl mx-auto px-4">
<h1 class="text-4xl font-semibold font-lato text-center pb-2">Blog</h1>
<div class="text-center mb-12">
<p class="font-sans lg:text-lg text-md text-gray-600 font-light mb-4">
Ramblings from coords and other friends. Learn something new
about technology, and maybe even yourself.
</p>
<a
href="https://github.com/UW-UPL/harvest/blob/main/docs/CONTRIBUTING.md"
class="text-red-600 hover:text-red-800 font-medium hover:underline"
target="_blank"
rel="noopener noreferrer"
>
Add your blog
</a>
</div>
<div class="space-y-8">
{posts.map((post) => {
let monthYear = null;
const currMonthYear = formatter.format(post.data.pubDate);
if (currMonthYear !== previousMonthYear) {
monthYear = (
<h2 class="text-2xl font-bold text-gray-700 mt-12 mb-6 first:mt-0">
{currMonthYear}
</h2>
);
previousMonthYear = currMonthYear;
}

return (
<>
{monthYear}
<BlogPostCard {...post} />
</>
);
})}
</div>
</div>
</Layout>

0 comments on commit 281dd26

Please sign in to comment.