mirror of
https://github.com/Fluffy-Bean/website.git
synced 2025-05-14 08:02:16 +00:00
Tags and Filtering
Yeet projects, as they're identical to posts in every way but name Add OpenGraph for SEO Add Plugin prop to Layout to avoid loading unnecessary JS and CSS
This commit is contained in:
parent
745ac58045
commit
291552c340
21 changed files with 336 additions and 212 deletions
|
@ -3,16 +3,15 @@ import { getMonth, getDaySuffix } from "../utils";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
post: any,
|
post: any,
|
||||||
base: string,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const { post, base } = Astro.props;
|
const { post } = Astro.props;
|
||||||
|
|
||||||
const date = new Date(post.data.pubDate);
|
const date = new Date(post.data.pubDate);
|
||||||
---
|
---
|
||||||
|
|
||||||
<li class="link-card">
|
<li class="link-card">
|
||||||
<a href=`${base}/${post.slug}`>
|
<a href=`/posts/${post.slug}`>
|
||||||
<h3>
|
<h3>
|
||||||
{post.data.title}
|
{post.data.title}
|
||||||
</h3>
|
</h3>
|
||||||
|
|
|
@ -1,28 +1,17 @@
|
||||||
import { z, defineCollection } from "astro:content";
|
import { z, defineCollection, reference } from "astro:content";
|
||||||
|
|
||||||
const postsCollection = defineCollection({
|
const posts = defineCollection({
|
||||||
type: "content",
|
type: "content",
|
||||||
schema: z.object({
|
schema: z.object({
|
||||||
draft: z.boolean().optional().default(false),
|
draft: z.boolean().optional().default(false),
|
||||||
title: z.string(),
|
title: z.string(),
|
||||||
description: z.string(),
|
description: z.string(),
|
||||||
pubDate: z.string().transform((str) => new Date(str)),
|
pubDate: z.string().transform((str) => new Date(str)),
|
||||||
tags: z.array(z.string()),
|
tags: z.array(reference("tags")),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
const projectsCollection = defineCollection({
|
const certificates = defineCollection({
|
||||||
type: "content",
|
|
||||||
schema: z.object({
|
|
||||||
draft: z.boolean().optional().default(false),
|
|
||||||
title: z.string(),
|
|
||||||
description: z.string(),
|
|
||||||
pubDate: z.string().transform((str) => new Date(str)),
|
|
||||||
tags: z.array(z.string()),
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
const certificatesCollection = defineCollection({
|
|
||||||
type: "data",
|
type: "data",
|
||||||
schema: z.object({
|
schema: z.object({
|
||||||
title: z.string(),
|
title: z.string(),
|
||||||
|
@ -33,8 +22,15 @@ const certificatesCollection = defineCollection({
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const tags = defineCollection({
|
||||||
|
type: "content",
|
||||||
|
schema: z.object({
|
||||||
|
name: z.string(),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
export const collections = {
|
export const collections = {
|
||||||
posts: postsCollection,
|
posts,
|
||||||
projects: projectsCollection,
|
certificates,
|
||||||
certificates: certificatesCollection,
|
tags,
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,7 +3,7 @@ title: "Code Examples"
|
||||||
description: "Aurghhhhhh"
|
description: "Aurghhhhhh"
|
||||||
pubDate: 2022-07-08
|
pubDate: 2022-07-08
|
||||||
tags:
|
tags:
|
||||||
- "Gaybo"
|
- "code"
|
||||||
---
|
---
|
||||||
|
|
||||||
```astro
|
```astro
|
||||||
|
|
|
@ -3,7 +3,7 @@ title: "Image Examples"
|
||||||
description: "fug"
|
description: "fug"
|
||||||
pubDate: 2024-07-08
|
pubDate: 2024-07-08
|
||||||
tags:
|
tags:
|
||||||
- "Faggo"
|
- "code"
|
||||||
---
|
---
|
||||||
|
|
||||||

|

|
||||||
|
|
|
@ -3,7 +3,8 @@ title: This is an example Post
|
||||||
description: "Cheat Sheet for Markdown"
|
description: "Cheat Sheet for Markdown"
|
||||||
pubDate: 2022-07-08
|
pubDate: 2022-07-08
|
||||||
tags:
|
tags:
|
||||||
- "Faggor"
|
- "code"
|
||||||
|
- "fortnite"
|
||||||
---
|
---
|
||||||
|
|
||||||
# Markdown Cheat Sheet
|
# Markdown Cheat Sheet
|
||||||
|
|
|
@ -3,7 +3,8 @@ title: "Math Examples"
|
||||||
description: "REEEEEE"
|
description: "REEEEEE"
|
||||||
pubDate: 2024-06-08
|
pubDate: 2024-06-08
|
||||||
tags:
|
tags:
|
||||||
- "Gaybo"
|
- "code"
|
||||||
|
- "math"
|
||||||
---
|
---
|
||||||
|
|
||||||
Some simple mathematical expressions:
|
Some simple mathematical expressions:
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
---
|
|
||||||
title: GwaGwa
|
|
||||||
description: This is a very very very very very very very very very very very very long description of a post
|
|
||||||
tags:
|
|
||||||
- "GwaGwa"
|
|
||||||
- "Gaming"
|
|
||||||
- "Urchin"
|
|
||||||
- "Fortnite"
|
|
||||||
---
|
|
||||||
|
|
||||||
Im actually going to blow up
|
|
||||||
|
|
||||||
I FUCKING HATE JAVASCRIPT
|
|
3
src/content/tags/code.md
Normal file
3
src/content/tags/code.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
name: Code
|
||||||
|
---
|
3
src/content/tags/fortnite.md
Normal file
3
src/content/tags/fortnite.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
name: Fortnite
|
||||||
|
---
|
4
src/content/tags/math.md
Normal file
4
src/content/tags/math.md
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
name: "Math"
|
||||||
|
---
|
||||||
|
``
|
|
@ -4,18 +4,33 @@ import Banner from "../assets/banner.png";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
title: string;
|
title: string;
|
||||||
|
plugins?: {
|
||||||
|
katex?: boolean,
|
||||||
|
}
|
||||||
|
seo?: {
|
||||||
|
description?: string,
|
||||||
|
tags?: string[],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const { title} = Astro.props;
|
const { title, plugins, seo} = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
|
<title>{title}</title>
|
||||||
|
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="description" content="Astro description" />
|
<meta name="description" content="Astro description" />
|
||||||
<meta name="viewport" content="width=device-width" />
|
<meta name="viewport" content="width=device-width" />
|
||||||
<meta name="generator" content={Astro.generator} />
|
<meta name="generator" content={Astro.generator} />
|
||||||
|
<meta name="keywords" content={seo?.tags ? seo?.tags.join(', ') : "furry, gay, homosegs"} />
|
||||||
|
|
||||||
|
<meta property="og:title" content={title} />
|
||||||
|
<meta property="og:description" content={seo?.description ? seo?.description : "Premium Legs only"} />
|
||||||
|
<meta property="og:url" content="https://gay.leggy.dev" />
|
||||||
|
<meta property="og:type" content="website" />
|
||||||
|
|
||||||
<link
|
<link
|
||||||
rel="icon"
|
rel="icon"
|
||||||
|
@ -27,29 +42,29 @@ const { title} = Astro.props;
|
||||||
href="https://api.fontshare.com/v2/css?f[]=jet-brains-mono@400&f[]=general-sans@1&display=swap"
|
href="https://api.fontshare.com/v2/css?f[]=jet-brains-mono@400&f[]=general-sans@1&display=swap"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<link
|
{plugins?.katex && (
|
||||||
rel="stylesheet"
|
<link
|
||||||
href="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/katex.min.css"
|
rel="stylesheet"
|
||||||
integrity="sha384-wcIxkf4k558AjM3Yz3BBFQUbk/zgIYC2R0QpeeYb+TwlBVMrlgLqwRjRtGZiK7ww"
|
href="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/katex.min.css"
|
||||||
crossorigin="anonymous"
|
integrity="sha384-wcIxkf4k558AjM3Yz3BBFQUbk/zgIYC2R0QpeeYb+TwlBVMrlgLqwRjRtGZiK7ww"
|
||||||
/>
|
crossorigin="anonymous"
|
||||||
<script
|
/>
|
||||||
is:inline
|
<script
|
||||||
defer
|
is:inline
|
||||||
src="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/katex.min.js"
|
defer
|
||||||
integrity="sha384-hIoBPJpTUs74ddyc4bFZSM1TVlQDA60VBbJS0oA934VSz82sBx1X7kSx2ATBDIyd"
|
src="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/katex.min.js"
|
||||||
crossorigin="anonymous"
|
integrity="sha384-hIoBPJpTUs74ddyc4bFZSM1TVlQDA60VBbJS0oA934VSz82sBx1X7kSx2ATBDIyd"
|
||||||
></script>
|
crossorigin="anonymous"
|
||||||
<script
|
></script>
|
||||||
is:inline
|
<script
|
||||||
defer
|
is:inline
|
||||||
src="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/contrib/auto-render.min.js"
|
defer
|
||||||
integrity="sha384-43gviWU0YVjaDtb/GhzOouOXtZMP/7XUzwPTstBeZFe/+rCMvRwr4yROQP43s0Xk"
|
src="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/contrib/auto-render.min.js"
|
||||||
crossorigin="anonymous"
|
integrity="sha384-43gviWU0YVjaDtb/GhzOouOXtZMP/7XUzwPTstBeZFe/+rCMvRwr4yROQP43s0Xk"
|
||||||
onload="renderMathInElement(document.body);"
|
crossorigin="anonymous"
|
||||||
></script>
|
onload="renderMathInElement(document.body);"
|
||||||
|
></script>
|
||||||
<title>{title}</title>
|
)}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="banner">
|
<div class="banner">
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
---
|
---
|
||||||
import { getMonth, getDaySuffix } from "../utils";
|
import { getMonth, getDaySuffix, getTagsBySlug } from "../utils";
|
||||||
|
import Layout from "./Layout.astro";
|
||||||
import HomeButton from "../components/HomeButton.astro";
|
import HomeButton from "../components/HomeButton.astro";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
@ -9,66 +10,88 @@ interface Props {
|
||||||
base: string,
|
base: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
const { post, prev, next, base } = Astro.props;
|
const { post, prev, next } = Astro.props;
|
||||||
|
|
||||||
|
// 183 average w/p
|
||||||
|
const readTime = `${Math.ceil(post.body.split(" ").length / 183)} min read`;
|
||||||
const date = new Date(post.data.pubDate);
|
const date = new Date(post.data.pubDate);
|
||||||
|
const tags = await getTagsBySlug(post.data.tags);
|
||||||
---
|
---
|
||||||
|
|
||||||
<HomeButton />
|
<Layout
|
||||||
|
title=`Leggy Land - ${post.data.title}`
|
||||||
|
plugins={{
|
||||||
|
katex: true,
|
||||||
|
}}
|
||||||
|
seo={{
|
||||||
|
description: post.data.description,
|
||||||
|
tags: post.data.tags,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<HomeButton />
|
||||||
|
|
||||||
<!-- If I ever move anything around, this will fucking break -->
|
<!-- If I ever move anything around, this will fucking break -->
|
||||||
<a href=`https://github.com/Fluffy-Bean/website/tree/main/src/content/${base}/${post.id}` id="source" class="button">
|
<a href=`https://github.com/Fluffy-Bean/website/tree/main/src/content/posts/${post.id}` id="source" class="button" aria-label="Source Code">
|
||||||
Source
|
<span>Source Code</span>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 256 256"><path d="M69.12,94.15,28.5,128l40.62,33.85a8,8,0,1,1-10.24,12.29l-48-40a8,8,0,0,1,0-12.29l48-40a8,8,0,0,1,10.24,12.3Zm176,27.7-48-40a8,8,0,1,0-10.24,12.3L227.5,128l-40.62,33.85a8,8,0,1,0,10.24,12.29l48-40a8,8,0,0,0,0-12.29ZM162.73,32.48a8,8,0,0,0-10.25,4.79l-64,176a8,8,0,0,0,4.79,10.26A8.14,8.14,0,0,0,96,224a8,8,0,0,0,7.52-5.27l64-176A8,8,0,0,0,162.73,32.48Z"></path></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 256 256"><path d="M69.12,94.15,28.5,128l40.62,33.85a8,8,0,1,1-10.24,12.29l-48-40a8,8,0,0,1,0-12.29l48-40a8,8,0,0,1,10.24,12.3Zm176,27.7-48-40a8,8,0,1,0-10.24,12.3L227.5,128l-40.62,33.85a8,8,0,1,0,10.24,12.29l48-40a8,8,0,0,0,0-12.29ZM162.73,32.48a8,8,0,0,0-10.25,4.79l-64,176a8,8,0,0,0,4.79,10.26A8.14,8.14,0,0,0,96,224a8,8,0,0,0,7.52-5.27l64-176A8,8,0,0,0,162.73,32.48Z"></path></svg>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<h1>{post.data.title}</h1>
|
<h1>{post.data.title}</h1>
|
||||||
{post.data.pubDate ? (
|
{post.data.pubDate ? (
|
||||||
<p>{date.getDate()}{getDaySuffix(date)} {getMonth(date)} {date.getFullYear()} • {post.data.description}</p>
|
<p>{date.getDate()}{getDaySuffix(date)} {getMonth(date)} {date.getFullYear()} • {readTime} • {post.data.description}</p>
|
||||||
) : (
|
) : (
|
||||||
<p>{post.data.description}</p>
|
<p>{readTime} • {post.data.description}</p>
|
||||||
)}
|
)}
|
||||||
<ul id="tags" class="pill-list" role="list">
|
<ul id="tags" class="pill-list" role="list">
|
||||||
{post.data.tags.map((item: string) => ( <li class="pill">#{item}</li> ))}
|
{tags.map((tag) => (
|
||||||
|
<li>
|
||||||
|
<a class="pill" href=`/search/${tag.slug}`>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" fill="currentColor" viewBox="0 0 256 256"><path d="M216,152H168V104h48a8,8,0,0,0,0-16H168V40a8,8,0,0,0-16,0V88H104V40a8,8,0,0,0-16,0V88H40a8,8,0,0,0,0,16H88v48H40a8,8,0,0,0,0,16H88v48a8,8,0,0,0,16,0V168h48v48a8,8,0,0,0,16,0V168h48a8,8,0,0,0,0-16Zm-112,0V104h48v48Z"></path></svg>
|
||||||
|
{tag.data.name}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
{post.data.base}
|
||||||
|
|
||||||
|
<div id="markdown">
|
||||||
|
<div style="margin-bottom: 32px" />
|
||||||
|
<slot></slot>
|
||||||
|
<div style="margin-top: 32px" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{(prev || next) && ( <hr> )}
|
||||||
|
|
||||||
|
<ul id="controls" role="list">
|
||||||
|
<li>
|
||||||
|
{prev && (
|
||||||
|
<a class="button" href=`/posts/${prev.slug}` id="prev">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 256 256"><path d="M224,128a8,8,0,0,1-8,8H59.31l58.35,58.34a8,8,0,0,1-11.32,11.32l-72-72a8,8,0,0,1,0-11.32l72-72a8,8,0,0,1,11.32,11.32L59.31,120H216A8,8,0,0,1,224,128Z"></path></svg>
|
||||||
|
Newer
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
{next && (
|
||||||
|
<a class="button" href=`/posts/${next.slug}` id="next">
|
||||||
|
Older
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 256 256"><path d="M221.66,133.66l-72,72a8,8,0,0,1-11.32-11.32L196.69,136H40a8,8,0,0,1,0-16H196.69L138.34,61.66a8,8,0,0,1,11.32-11.32l72,72A8,8,0,0,1,221.66,133.66Z"></path></svg>
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</Layout>
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<div id="markdown">
|
|
||||||
<div style="margin-bottom: 32px" />
|
|
||||||
<slot></slot>
|
|
||||||
<div style="margin-top: 32px" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{(prev || next) && ( <hr> )}
|
|
||||||
|
|
||||||
<ul id="controls" role="list">
|
|
||||||
<li>
|
|
||||||
{prev && (
|
|
||||||
<a class="button" href=`/${base}/${prev.slug}` id="prev">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 256 256"><path d="M224,128a8,8,0,0,1-8,8H59.31l58.35,58.34a8,8,0,0,1-11.32,11.32l-72-72a8,8,0,0,1,0-11.32l72-72a8,8,0,0,1,11.32,11.32L59.31,120H216A8,8,0,0,1,224,128Z"></path></svg>
|
|
||||||
Newer
|
|
||||||
</a>
|
|
||||||
)}
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
{next && (
|
|
||||||
<a class="button" href=`/${base}/${next.slug}` id="next">
|
|
||||||
Older
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 256 256"><path d="M221.66,133.66l-72,72a8,8,0,0,1-11.32-11.32L196.69,136H40a8,8,0,0,1,0-16H196.69L138.34,61.66a8,8,0,0,1,11.32-11.32l72,72A8,8,0,0,1,221.66,133.66Z"></path></svg>
|
|
||||||
</a>
|
|
||||||
)}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
|
|
||||||
<style is:global lang="scss">
|
<style is:global lang="scss">
|
||||||
@import "../styles/vars";
|
@import "../styles/vars";
|
||||||
|
|
||||||
#source {
|
#source {
|
||||||
padding: 0 20px;
|
padding: 0 10px;
|
||||||
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 8px;
|
top: 8px;
|
||||||
|
@ -77,10 +100,28 @@ const date = new Date(post.data.pubDate);
|
||||||
border-top-right-radius: 0;
|
border-top-right-radius: 0;
|
||||||
border-bottom-right-radius: 0;
|
border-bottom-right-radius: 0;
|
||||||
|
|
||||||
&:before {
|
transition: padding 1s cubic-bezier(0, 1, 0, 1);
|
||||||
|
|
||||||
|
> span {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
border-top-right-radius: 0;
|
border-top-right-radius: 0;
|
||||||
border-bottom-right-radius: 0;
|
border-bottom-right-radius: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
padding: 0 20px;
|
||||||
|
|
||||||
|
> span {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
> svg {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*#source {*/
|
/*#source {*/
|
||||||
|
@ -186,49 +227,41 @@ const date = new Date(post.data.pubDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
table {
|
table {
|
||||||
|
margin: 16px 0;
|
||||||
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
/*border: 1px solid $gray;*/
|
font-size: 13px;
|
||||||
|
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
|
/*border: 2px solid $gray;*/
|
||||||
|
|
||||||
tr {
|
tr {
|
||||||
/*border-bottom: 1px solid $gray;*/
|
|
||||||
|
|
||||||
&:nth-child(even) td {
|
&:nth-child(even) td {
|
||||||
background-color: rgba($gray, 0.35);
|
background-color: rgba($gray, 0.15);
|
||||||
}
|
}
|
||||||
|
&:last-of-type > td {
|
||||||
&:last-of-type {
|
/*border-bottom: 2px solid $gray;*/
|
||||||
/*border: 0 solid transparent;*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
td {
|
td {
|
||||||
padding: 8px 16px;
|
padding: 8px 16px;
|
||||||
|
|
||||||
font-size: 13px;
|
|
||||||
|
|
||||||
border-right: 1px solid $gray;
|
|
||||||
|
|
||||||
&:first-child {
|
&:first-child {
|
||||||
border-bottom-left-radius: $radius;
|
border-bottom-left-radius: $radius;
|
||||||
}
|
}
|
||||||
&:last-child {
|
&:last-child {
|
||||||
border-bottom-right-radius: $radius;
|
border-bottom-right-radius: $radius;
|
||||||
}
|
}
|
||||||
&:last-of-type {
|
|
||||||
border-right: 0 solid transparent;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
th {
|
th {
|
||||||
padding: 8px 16px;
|
padding: 8px 16px;
|
||||||
|
|
||||||
font-size: 13px;
|
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
|
||||||
background-color: rgba($accent, 0.3);
|
border-bottom: 2px solid darken($gray, 2%);
|
||||||
color: $light;
|
background-color: $gray;
|
||||||
|
|
||||||
&:first-child {
|
&:first-child {
|
||||||
border-top-left-radius: $radius;
|
border-top-left-radius: $radius;
|
||||||
|
@ -259,6 +292,7 @@ const date = new Date(post.data.pubDate);
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
|
|
||||||
border-radius: $radius;
|
border-radius: $radius;
|
||||||
|
border: 2px solid rgba(#000, 0.1);
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
content: attr(data-language);
|
content: attr(data-language);
|
||||||
|
@ -279,6 +313,8 @@ const date = new Date(post.data.pubDate);
|
||||||
border-bottom-right-radius: 9999px;
|
border-bottom-right-radius: 9999px;
|
||||||
background-color: $gray;
|
background-color: $gray;
|
||||||
color: $light;
|
color: $light;
|
||||||
|
|
||||||
|
z-index: +1;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:focus-visible {
|
&:focus-visible {
|
||||||
|
|
|
@ -11,7 +11,6 @@ const tools = ["Proxmox", "JetBrain IDEs", "Docker", "Linux", "SQLite", "Postgre
|
||||||
const languages = ["Go", "Python", "HTML", "CSS", "Sass", "TypeScript", "JavaScript", "Scratch", "PHP", "SQL", "Bash"];
|
const languages = ["Go", "Python", "HTML", "CSS", "Sass", "TypeScript", "JavaScript", "Scratch", "PHP", "SQL", "Bash"];
|
||||||
const frameworks = ["Gin", "Echo", "Flask", "Svelte", "Astro", "raylib"];
|
const frameworks = ["Gin", "Echo", "Flask", "Svelte", "Astro", "raylib"];
|
||||||
const certificates = await getCollection("certificates");
|
const certificates = await getCollection("certificates");
|
||||||
const projects = await getPosts("projects");
|
|
||||||
const posts = await getPosts("posts");
|
const posts = await getPosts("posts");
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -78,6 +77,16 @@ const posts = await getPosts("posts");
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<h2>Recent Posts</h2>
|
||||||
|
<ul class="project-list" role="list">
|
||||||
|
{posts.slice(0, 2).map(post => (
|
||||||
|
<Card {post} />
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
<a class="button" id="see-all-posts" href="/posts">All Posts</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<h2>Certificates</h2>
|
<h2>Certificates</h2>
|
||||||
<ul class="project-list" role="list">
|
<ul class="project-list" role="list">
|
||||||
|
@ -88,26 +97,6 @@ const posts = await getPosts("posts");
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="section">
|
|
||||||
<h2>Projects</h2>
|
|
||||||
<ul class="project-list" role="list">
|
|
||||||
{projects.slice(0, 2).map(post => (
|
|
||||||
<Card {post} base="/projects"/>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
<a class="button" id="see-all-projects" href="/projects">All Projects</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="section">
|
|
||||||
<h2>Recent Posts</h2>
|
|
||||||
<ul class="project-list" role="list">
|
|
||||||
{posts.slice(0, 2).map(post => (
|
|
||||||
<Card {post} base="/posts" />
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
<a class="button" id="see-all-posts" href="/posts">All Posts</a>
|
|
||||||
</div>
|
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
---
|
---
|
||||||
import { getPosts } from "../../utils";
|
import { getPosts } from "../../utils";
|
||||||
import Layout from "../../layouts/Layout.astro";
|
|
||||||
import Markdown from "../../layouts/Markdown.astro";
|
import Markdown from "../../layouts/Markdown.astro";
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
|
@ -21,8 +20,6 @@ const { post, prev, next } = Astro.props;
|
||||||
const { Content } = await post.render();
|
const { Content } = await post.render();
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title=`Leggy Land - ${post.data.title}`>
|
<Markdown post={post} prev={prev} next={next} base="posts">
|
||||||
<Markdown post={post} prev={prev} next={next} base="posts">
|
<Content />
|
||||||
<Content />
|
</Markdown>
|
||||||
</Markdown>
|
|
||||||
</Layout>
|
|
||||||
|
|
|
@ -10,16 +10,44 @@ const posts = await getPosts("posts");
|
||||||
<Layout title="Leggy Land - All Posts">
|
<Layout title="Leggy Land - All Posts">
|
||||||
<HomeButton />
|
<HomeButton />
|
||||||
|
|
||||||
|
<a href="/search" id="search" class="button" aria-label="Search">
|
||||||
|
Search
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 256 256"><path d="M230.6,49.53A15.81,15.81,0,0,0,216,40H40A16,16,0,0,0,28.19,66.76l.08.09L96,139.17V216a16,16,0,0,0,24.87,13.32l32-21.34A16,16,0,0,0,160,194.66V139.17l67.74-72.32.08-.09A15.8,15.8,0,0,0,230.6,49.53ZM40,56h0Zm106.18,74.58A8,8,0,0,0,144,136v58.66L112,216V136a8,8,0,0,0-2.16-5.47L40,56H216Z"></path></svg>
|
||||||
|
</a>
|
||||||
|
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<h1>All Posts</h1>
|
<h1>All Posts</h1>
|
||||||
<p>Egg Book</p>
|
<p>Books of egg</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<ul role="list" class="project-list">
|
<ul role="list" class="project-list">
|
||||||
{posts.map(post => (
|
{posts.map(post => (
|
||||||
<Card {post} base="/posts"/>
|
<Card {post}/>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
|
<style is:global lang="scss">
|
||||||
|
@import "../../styles/vars";
|
||||||
|
|
||||||
|
#search {
|
||||||
|
padding: 0 20px;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
top: 8px;
|
||||||
|
right: 0;
|
||||||
|
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
|
||||||
|
transition: padding 1s cubic-bezier(0, 1, 0, 1);
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
---
|
|
||||||
import { getPosts } from "../../utils";
|
|
||||||
import Layout from "../../layouts/Layout.astro";
|
|
||||||
import Markdown from "../../layouts/Markdown.astro";
|
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
|
||||||
const collection = await getPosts("projects");
|
|
||||||
|
|
||||||
return collection.map((post, i) => ({
|
|
||||||
params: { slug: post.slug },
|
|
||||||
props: {
|
|
||||||
post: post,
|
|
||||||
prev: i > 0 ? collection[i - 1] : undefined,
|
|
||||||
next: i < collection.length - 1 ? collection[i + 1] : undefined
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
const { post, prev, next } = Astro.props;
|
|
||||||
|
|
||||||
const { Content } = await post.render();
|
|
||||||
---
|
|
||||||
|
|
||||||
<Layout title=`Leggy Land - ${post.data.title}`>
|
|
||||||
<Markdown post={post} prev={prev} next={next} base="projects">
|
|
||||||
<Content />
|
|
||||||
</Markdown>
|
|
||||||
</Layout>
|
|
|
@ -1,25 +0,0 @@
|
||||||
---
|
|
||||||
import { getPosts } from "../../utils";
|
|
||||||
import Layout from "../../layouts/Layout.astro";
|
|
||||||
import Card from "../../components/Card.astro";
|
|
||||||
import HomeButton from "../../components/HomeButton.astro";
|
|
||||||
|
|
||||||
const projects = await getPosts("projects");
|
|
||||||
---
|
|
||||||
|
|
||||||
<Layout title="Leggy Land - All Projects">
|
|
||||||
<HomeButton />
|
|
||||||
|
|
||||||
<div class="header">
|
|
||||||
<h1>All Projects</h1>
|
|
||||||
<p>Come back next week for 4 new projects!</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<ul role="list" class="project-list">
|
|
||||||
{projects.map(post => (
|
|
||||||
<Card {post} base="/projects"/>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</Layout>
|
|
70
src/pages/search/[filter].astro
Normal file
70
src/pages/search/[filter].astro
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
---
|
||||||
|
import { getCollection } from "astro:content";
|
||||||
|
|
||||||
|
import { getPosts } from "../../utils";
|
||||||
|
import Layout from "../../layouts/Layout.astro";
|
||||||
|
import Card from "../../components/Card.astro";
|
||||||
|
import HomeButton from "../../components/HomeButton.astro";
|
||||||
|
|
||||||
|
export async function getStaticPaths() {
|
||||||
|
const collection = await getCollection("tags");
|
||||||
|
|
||||||
|
// Filter by file name, such as linux-kernel instead of "Linux Kernel"
|
||||||
|
return collection.map((tag) => ({
|
||||||
|
params: { filter: tag.slug },
|
||||||
|
props: { tag }
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
const { tag } = Astro.props;
|
||||||
|
|
||||||
|
const allPosts = await getPosts("posts");
|
||||||
|
const filteredPosts = allPosts.filter((project) => project.data.tags.includes(tag.slug));
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title=`Leggy Land - Searching for ${tag.data.name}`>
|
||||||
|
<HomeButton />
|
||||||
|
|
||||||
|
<a href="/search" id="reset-filters" class="button" aria-label="Reset Filters">
|
||||||
|
Reset Filters
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 256 256"><path d="M227.82,66.76A16,16,0,0,0,216,40H40A16,16,0,0,0,28.19,66.76l.08.09L96,139.17V216a16,16,0,0,0,24.87,13.32l32-21.34A16,16,0,0,0,160,194.66V139.17l67.73-72.32ZM40,56h0Zm106.19,74.59A8,8,0,0,0,144,136v58.66L112,216V136a8,8,0,0,0-2.16-5.46L40,56H216Zm99.49,79.81a8,8,0,0,1-11.32,11.32L216,203.32l-18.34,18.35a8,8,0,0,1-11.31-11.32L204.69,192l-18.34-18.35a8,8,0,0,1,11.31-11.31L216,180.69l18.34-18.34a8,8,0,0,1,11.32,11.31L227.31,192Z"></path></svg>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="header">
|
||||||
|
<h1>Search: {tag.data.name}</h1>
|
||||||
|
<p>Showing {filteredPosts.length}/{allPosts.length} posts</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<ul role="list" class="project-list">
|
||||||
|
{filteredPosts.map(post => (
|
||||||
|
<Card {post} />
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</Layout>
|
||||||
|
|
||||||
|
<style is:global lang="scss">
|
||||||
|
@import "../../styles/vars";
|
||||||
|
|
||||||
|
#reset-filters {
|
||||||
|
padding: 0 20px;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
top: 8px;
|
||||||
|
right: 0;
|
||||||
|
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
|
||||||
|
transition: padding 1s cubic-bezier(0, 1, 0, 1);
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
36
src/pages/search/index.astro
Normal file
36
src/pages/search/index.astro
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
---
|
||||||
|
import { getCollection} from "astro:content";
|
||||||
|
|
||||||
|
import { getPosts } from "../../utils";
|
||||||
|
import Layout from "../../layouts/Layout.astro";
|
||||||
|
import HomeButton from "../../components/HomeButton.astro";
|
||||||
|
|
||||||
|
const tags = await getCollection("tags");
|
||||||
|
const posts = await getPosts("posts");
|
||||||
|
tags.forEach((tag) => {
|
||||||
|
tag.data.postCount = posts.filter((project) => {
|
||||||
|
return project.data.tags.includes(tag.slug);
|
||||||
|
}).length;
|
||||||
|
})
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title="Leggy Land - All Projects">
|
||||||
|
<HomeButton />
|
||||||
|
|
||||||
|
<div class="header">
|
||||||
|
<h1>Search</h1>
|
||||||
|
<p>Filter posts by tags</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<ul role="list" class="pill-list">
|
||||||
|
{tags.map(tag => (
|
||||||
|
<li>
|
||||||
|
<a class="button" href=`/search/${tag.slug}`>
|
||||||
|
{tag.data.name} {tag.data.postCount}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</Layout>
|
|
@ -13,6 +13,7 @@
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
|
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
|
||||||
border-radius: 9999px;
|
border-radius: 9999px;
|
||||||
|
|
13
src/utils.ts
13
src/utils.ts
|
@ -1,4 +1,4 @@
|
||||||
import { type ContentEntryMap, getCollection } from "astro:content";
|
import {type CollectionEntry, type ContentEntryMap, getCollection} from "astro:content";
|
||||||
|
|
||||||
// https://github.com/hellotham/hello-astro/blob/e05706cf488bcec6e4c5494a622eedfc4e47d763/src/config.ts#L55C1-L62C2
|
// https://github.com/hellotham/hello-astro/blob/e05706cf488bcec6e4c5494a622eedfc4e47d763/src/config.ts#L55C1-L62C2
|
||||||
export async function getPosts(collection: keyof ContentEntryMap) {
|
export async function getPosts(collection: keyof ContentEntryMap) {
|
||||||
|
@ -43,3 +43,14 @@ export function getDaySuffix(date: Date): string {
|
||||||
|
|
||||||
return suffix;
|
return suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getTagsBySlug(postTags: string[]): Promise<CollectionEntry<"tags">[]> {
|
||||||
|
const allTags: CollectionEntry<"tags">[] = await getCollection("tags");
|
||||||
|
const tags: CollectionEntry<"tags">[] = [];
|
||||||
|
postTags.forEach((postTag) => {
|
||||||
|
allTags.forEach((allTag) => {
|
||||||
|
if (allTag.slug == postTag) tags.push(allTag);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return tags;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue