This commit is contained in:
Mrrp 2025-01-04 12:20:53 -08:00
parent 6c2bae94d8
commit 2d78426857
11 changed files with 159 additions and 101 deletions

View file

@ -25,34 +25,10 @@ concurrency:
cancel-in-progress: false cancel-in-progress: false
jobs: jobs:
# Add/update json to branch commit before building
# then upload the artifact to the git repository for storage (permanent)
prepare:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Activate Venv
run: source venv/bin/activate
- name: Setup Deno
uses: denoland/setup-deno@v2
with:
deno-version: v2.x
- name: Install dependencies
run: pip install python-frontmatter && deno install
- name: Update Page list
run: deno --allow-all utils/page_updater/update_pagelist.ts
# - name: Update Page history
# run: python utils/page_updater/commit_post_history.py
# - name: Generate RSS feed
# run: python utils/page_updater/rss_xml_gen.py
- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v5
# Build job # Build job
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: prepare
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
@ -71,6 +47,8 @@ jobs:
${{ runner.os }}-nuxt-build- ${{ runner.os }}-nuxt-build-
- name: Install dependencies - name: Install dependencies
run: deno install run: deno install
- name: Update Page list
run: deno --allow-all utils/page_updater/update_pagelist.ts
- name: Generate project as a static site - name: Generate project as a static site
run: deno task generate run: deno task generate
- name: Upload artifact - name: Upload artifact

View file

@ -1,27 +1,13 @@
{ {
"last_generated": "2025-01-04 19:51:50", "last_generated": "2025-01-04 12:04:30",
"categories": { "categories": {
"Blog": { "Blog": {
"posts": [ "posts": [
{
"metadata": {
"title": "LGBTQ+ Resources",
"description": "A list of resources for LGBTQ+ individuals",
"date": "2025-01-02 00:00:00",
"tags": [
"lgbtq+",
"resources"
]
},
"id": "blog/lgbtq_resources.md",
"url": "/blog/lgbtq_resources.md",
"hash": "3da76064aa95cc06937bde01128ed44aafb850f35a43bd214ce0cd89a875c674"
},
{ {
"metadata": { "metadata": {
"title": "3DS Programming - Using RomFS", "title": "3DS Programming - Using RomFS",
"description": "A guide to using RomFS on the 3DS. (Old)", "description": "A guide to using RomFS on the 3DS. (Old)",
"date": "2025-01-01 00:00:00", "date": "2024-12-31 16:00:00",
"tags": [ "tags": [
"3ds", "3ds",
"programming", "programming",
@ -36,43 +22,11 @@
"url": "/blog/old3ds_romfs.md", "url": "/blog/old3ds_romfs.md",
"hash": "0b28a366868e9fa564b6a33d9b1aa1d8269f7971497f25488f05f54929e88410" "hash": "0b28a366868e9fa564b6a33d9b1aa1d8269f7971497f25488f05f54929e88410"
}, },
{
"metadata": {
"title": "Styling Test",
"description": "A test post to see how the site styling looks",
"date": "2025-01-01 00:00:00",
"tags": [
"meta",
"web"
]
},
"id": "blog/styling_test.md",
"url": "/blog/styling_test.md",
"hash": "0ff9f34321a27f462ca26656a1dc5024c0e800ea1e176ff36316b158ab4606c9"
},
{
"metadata": {
"title": "3DS Programming - Hello World",
"description": "A guide to creating a simple Hello, World program for the 3DS. (Old)",
"date": "2025-01-01 00:00:00",
"tags": [
"3ds",
"programming",
"c",
"devkitpro",
"old"
],
"next": "old3ds_romfs.md"
},
"id": "blog/old3ds_helloworld.md",
"url": "/blog/old3ds_helloworld.md",
"hash": "86e0bd1deae0d00b17ab0960634ea7292d6387063f70600cec4001564fde9514"
},
{ {
"metadata": { "metadata": {
"title": "3DS Programming - Touchscreen Input", "title": "3DS Programming - Touchscreen Input",
"description": "A guide to using the touchscreen on the 3DS. (Old)", "description": "A guide to using the touchscreen on the 3DS. (Old)",
"date": "2025-01-01 00:00:00", "date": "2024-12-31 16:00:00",
"tags": [ "tags": [
"3ds", "3ds",
"programming", "programming",
@ -86,39 +40,105 @@
"url": "/blog/old3ds_touchscreen.md", "url": "/blog/old3ds_touchscreen.md",
"hash": "59e0b9d701646fd5f747713832c47ce451e0ebe0975d4a148a820ca795741c2b" "hash": "59e0b9d701646fd5f747713832c47ce451e0ebe0975d4a148a820ca795741c2b"
}, },
{
"metadata": {
"title": "3DS Programming - Hello World",
"description": "A guide to creating a simple Hello, World program for the 3DS. (Old)",
"date": "2024-12-31 16:00:00",
"tags": [
"3ds",
"programming",
"c",
"devkitpro",
"old"
],
"next": "old3ds_romfs.md"
},
"id": "blog/old3ds_helloworld.md",
"url": "/blog/old3ds_helloworld.md",
"hash": "86e0bd1deae0d00b17ab0960634ea7292d6387063f70600cec4001564fde9514"
}
],
"title": "Blog",
"description": "General blog posts",
"tags": [
"blog"
]
},
"Site": {
"posts": [
{
"metadata": {
"title": "Styling Test",
"description": "A test post to see how the site styling looks",
"date": "2024-12-31 16:00:00",
"tags": [
"meta",
"web"
]
},
"id": "site/styling_test.md",
"url": "/site/styling_test.md",
"hash": "0ff9f34321a27f462ca26656a1dc5024c0e800ea1e176ff36316b158ab4606c9"
}
],
"title": "Site",
"description": "Articles to test site functionality",
"tags": [
"site"
]
},
"Collections": {
"posts": [
{
"metadata": {
"title": "LGBTQ+ Resources",
"description": "A list of resources for LGBTQ+ individuals",
"date": "2025-01-01 16:00:00",
"tags": [
"lgbtq+",
"resources"
]
},
"id": "collections/lgbtq_resources.md",
"url": "/collections/lgbtq_resources.md",
"hash": "3da76064aa95cc06937bde01128ed44aafb850f35a43bd214ce0cd89a875c674"
},
{ {
"metadata": { "metadata": {
"title": "Badges!", "title": "Badges!",
"description": "A collection of 88x31 badges for various things", "description": "A collection of 88x31 badges for various things",
"date": "2024-12-21 00:00:00", "date": "2024-12-20 16:00:00",
"tags": [ "tags": [
"badges", "badges",
"retro", "retro",
"web" "web"
] ]
}, },
"id": "blog/badges.md", "id": "collections/badges.md",
"url": "/blog/badges.md", "url": "/collections/badges.md",
"hash": "338ccfecc6523dff93708330a8b43af715f1e80d55e1cc3bea2d1a7306fc4f00" "hash": "338ccfecc6523dff93708330a8b43af715f1e80d55e1cc3bea2d1a7306fc4f00"
}, },
{ {
"metadata": { "metadata": {
"title": "Awesome", "title": "Awesome",
"description": "A curated list of awesome stuff I like", "description": "A curated list of awesome stuff I like",
"date": "2024-11-26 00:00:00", "date": "2024-11-25 16:00:00",
"tags": [ "tags": [
"awesome", "awesome",
"curated" "curated"
] ]
}, },
"id": "blog/awesome.md", "id": "collections/awesome.md",
"url": "/blog/awesome.md", "url": "/collections/awesome.md",
"hash": "0632400858006b93f2f36d87953538c2a400bacc75aaa29928aee226e8b343b1" "hash": "0632400858006b93f2f36d87953538c2a400bacc75aaa29928aee226e8b343b1"
} }
], ],
"title": "", "title": "Collections",
"description": "", "description": "Articles that are collections of information: Lists, Awesome lists, etc.",
"tags": [] "tags": [
"collection"
]
} }
} }
} }

View file

@ -9,7 +9,7 @@ import Card from './Card.vue';
<Card> <Card>
<div class="flex justify-center"> <div class="flex justify-center">
<NuxtLink href="/" class="transition text-xl pl-2 pr-2 ease-in-out text-purple-100 hover:text-purple-400 duration-200">Home</NuxtLink> <NuxtLink href="/" class="transition text-xl pl-2 pr-2 ease-in-out text-purple-100 hover:text-purple-400 duration-200">Home</NuxtLink>
<NuxtLink href="/article/" class="transition text-xl pl-2 pr-2 ease-in-out text-purple-100 hover:text-purple-400 duration-200">Blog</NuxtLink> <NuxtLink href="/article/" class="transition text-xl pl-2 pr-2 ease-in-out text-purple-100 hover:text-purple-400 duration-200">Articles</NuxtLink>
<NuxtLink href="/article/blog/awesome.md" class="transition text-xl pl-2 pr-2 ease-in-out text-purple-100 hover:text-purple-400 duration-200">Awesome</NuxtLink> <NuxtLink href="/article/blog/awesome.md" class="transition text-xl pl-2 pr-2 ease-in-out text-purple-100 hover:text-purple-400 duration-200">Awesome</NuxtLink>
<NuxtLink href="/article/blog/badges.md" class="transition text-xl pl-2 pr-2 ease-in-out text-purple-100 hover:text-purple-400 duration-200">Badges</NuxtLink> <NuxtLink href="/article/blog/badges.md" class="transition text-xl pl-2 pr-2 ease-in-out text-purple-100 hover:text-purple-400 duration-200">Badges</NuxtLink>
</div> </div>

View file

@ -1,6 +1,6 @@
import * as pages from '~/utils/page_updater/update_pagelist'; import * as pages from '~/utils/page_updater/update_pagelist';
const blog_list: pages.PageList = (await import('./assets/meta/blog_list.json')) as pages.PageList; const blog_list: pages.PageList = (await import('./assets/meta/post_list.json')) as pages.PageList;
// nitro only needs string array // nitro only needs string array
const blog_nitro_routes: any = []; const blog_nitro_routes: any = [];

View file

@ -9,16 +9,18 @@ import type { ParsedContent } from '@nuxt/content';
// Automatically maintained is a blog_list.json in assets/meta. This file contains a list of all blog posts and their metadata. // Automatically maintained is a blog_list.json in assets/meta. This file contains a list of all blog posts and their metadata.
// This file is generated by a script in the utils/pageupdater folder. // This file is generated by a script in the utils/pageupdater folder.
const article_list: pages.PageList = await import('~/assets/meta/blog_list.json') as pages.PageList; const article_list: pages.PageList = await import('~/assets/meta/post_list.json') as pages.PageList;
let route = useRoute() let route = useRoute()
console.log(route) console.log(route)
const loading: Ref<boolean> = ref(false) const loading: Ref<boolean> = ref(false)
const view: Ref<string> = ref('list') // list, category
const listCategoryKeys: Ref<string[]> = ref([]) const listCategoryKeys: Ref<string[]> = ref([])
const tagList: Ref<string[]> = ref([]) const tagList: Ref<string[]> = ref([])
const categoryFilter: Ref<string[]> = ref([])
const tagFilter: Ref<string[]> = ref([]) const tagFilter: Ref<string[]> = ref([])
tagFilter.value = [] tagFilter.value = []
@ -49,18 +51,28 @@ onMounted(() => {
<template> <template>
<div class="relative z-50 flex w-full justify-center text-white"> <div class="relative z-50 flex w-full justify-center text-white">
<!-- Metadata --> <!-- Metadata -->
<MetaSet title="Articles" description="Ramblings." background="https://avatars.githubusercontent.com/u/94077364?v=4" <MetaSet title="Articles" description="Ramblings."
tags="blog, personal, author" /> background="https://avatars.githubusercontent.com/u/94077364?v=4" tags="blog, personal, author" />
<!-- Main Content --> <!-- Main Content -->
<div class="mt-8 flex-col text-center"> <div class="mt-8 flex-col text-center">
<Transition name="list"> <Transition name="list">
<div> <div>
<!-- Article List --> <!-- Article List -->
<h1>Articles</h1> <h1>Articles</h1>
<div class="flex justify-center">
<div class="flex flex-wrap justify-center m-5 max-w-96"> <!-- View mode switcher -->
<div class="flex justify-center">
<button @click="view = 'list'"
class="m-1 bg-black border-purple-400 border text-white p-1 rounded-md"
:class="view == 'list' ? 'border-2 border-white bg-slate-700' : 'border-2 bg-black text-white'">List</button>
<button @click="view = 'category'"
class="m-1 bg-black border-purple-400 border text-white p-1 rounded-md"
:class="view == 'category' ? 'border-2 border-white bg-slate-700' : 'border-2 bg-black text-white'">Category</button>
</div>
<!-- Tag selection -->
<div class="flex justify-center" v-if="view == 'list'">
<div class="flex flex-wrap justify-center m-5 max-w-96">
<div v-for="tag in tagList" :key="tag" class="m-1"> <div v-for="tag in tagList" :key="tag" class="m-1">
<button <button
@click="tagFilter.includes(tag) ? tagFilter.splice(tagFilter.indexOf(tag), 1) : tagFilter.push(tag)" @click="tagFilter.includes(tag) ? tagFilter.splice(tagFilter.indexOf(tag), 1) : tagFilter.push(tag)"
@ -70,22 +82,53 @@ onMounted(() => {
</div> </div>
</div> </div>
</div> </div>
<div> <!-- Category selection -->
<div v-for="categoryKey in Object.keys(article_list.categories)" :key="categoryKey"> <div class="flex justify-center" v-if="view == 'category'">
<div class="lg:w-[48rem] md:w-max flex flex-col bg-secondary bg-opacity-50 rounded-md shadow-md shadow-secondary p-2 m-2"> <div class="flex flex-wrap justify-center m-5 max-w-96">
<div v-for="category in Object.keys(article_list.categories)" :key="category"
class="m-1">
<button
@click="categoryFilter.includes(category) ? categoryFilter.splice(categoryFilter.indexOf(category), 1) : categoryFilter.push(category)"
class="text-xs bg-black border-purple-400 border text-white p-1 rounded-md"
:class="categoryFilter.includes(category) ? 'border-2 border-white bg-slate-700' : 'border-2 bg-black text-white'">{{
category }}</button>
</div>
</div>
</div>
<!-- Category view -->
<div v-if="view == 'category'">
<div v-for="categoryKey in Object.keys(article_list.categories).filter((category) => categoryFilter.length == 0 ? true : categoryFilter.includes(category))" :key="categoryKey">
<div
class="lg:w-[48rem] md:w-max flex flex-col bg-secondary bg-opacity-50 rounded-md shadow-md shadow-secondary p-2 m-2 mb-8">
<h2>{{ categoryKey }}</h2> <h2>{{ categoryKey }}</h2>
<div <div
v-for="post in tagFilter.length == 0 ? article_list.categories[categoryKey].posts : article_list.categories[categoryKey].posts.filter((post) => post.metadata.tags ? post.metadata.tags.some((tag) => tagFilter.includes(tag)) : true)"> v-for="post in article_list.categories[categoryKey].posts">
<PostCard class="lg:w-[48rem]" :url="post.url" :key="post.id" :tagFilter="tagFilter" /> <PostCard class="lg:w-[48rem]" :url="post.url" :key="post.id"
:tagFilter="tagFilter" />
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!-- List view -->
<!-- Instead of grouping by category, just throw cards by order of appearance -->
<div v-else-if="view == 'list'">
<div
v-for="post in tagFilter.length == 0 ?
Object.values(article_list.categories)
.map((category) => category.posts)
.flat()
: Object.values(article_list.categories)
.map((category) => category.posts)
.flat()
.filter((post) => post.metadata.tags ? post.metadata.tags.some((tag) => tagFilter.includes(tag)) : true)
">
<PostCard class="lg:w-[48rem]" :url="post.url" :key="post.id" :tagFilter="tagFilter" />
</div>
</div>
</div> </div>
</Transition> </Transition>
</div> </div>
</div> </div>
</template> </template>
<style scoped> <style scoped></style>
</style>

View file

@ -56,5 +56,5 @@ post_list = generate_page_list(pages.get_pages_info("", "assets/blog"));
print(post_list) print(post_list)
# Output to assets/blog_list.json (overwriting) # Output to assets/blog_list.json (overwriting)
with open("assets/blog_list.json", "w") as f: with open("assets/meta/post_list.json", "w") as f:
f.write(post_list) f.write(post_list)

View file

@ -54,10 +54,24 @@ function generatePageCategory(pagesInfo: Record<string, any>): PageCategory {
const postDirectories: pages.PageLocation[] = [ const postDirectories: pages.PageLocation[] = [
{ {
title: "Blog", title: "Blog",
description: "A collection of blog posts", description: "General blog posts",
tags: ["blog"], tags: ["blog"],
map: "blog", map: "blog",
root: "content/blog" root: "content/blog"
},
{
title: "Site",
description: "Articles to test site functionality",
tags: ["site"],
map: "site",
root: "content/site"
},
{
title: "Collections",
description: "Articles that are collections of information: Lists, Awesome lists, etc.",
tags: ["collection"],
map: "collections",
root: "content/collections"
} }
] ]
@ -69,6 +83,9 @@ var postList: PageList = {
for (const postDirectory of postDirectories) { for (const postDirectory of postDirectories) {
const pagesInfo = pages.getPagesInfo("", postDirectory); const pagesInfo = pages.getPagesInfo("", postDirectory);
postList.categories[postDirectory.title] = generatePageCategory(pagesInfo); postList.categories[postDirectory.title] = generatePageCategory(pagesInfo);
postList.categories[postDirectory.title].title = postDirectory.title;
postList.categories[postDirectory.title].description = postDirectory.description;
postList.categories[postDirectory.title].tags = postDirectory.tags;
} }
// Sort the posts by date // Sort the posts by date
@ -87,4 +104,4 @@ for (const category of Object.values(postList.categories)) {
console.log(JSON.stringify(postList, null, 2)); console.log(JSON.stringify(postList, null, 2));
// Output to assets/blog_list.json (overwriting) // Output to assets/blog_list.json (overwriting)
fs.writeFileSync("assets/meta/blog_list.json", JSON.stringify(postList, null, 2)); fs.writeFileSync("assets/meta/post_list.json", JSON.stringify(postList, null, 2));