Many many changes
This commit is contained in:
parent
0ccbcacf6f
commit
c0a63a4a97
23 changed files with 405 additions and 20 deletions
|
@ -10,8 +10,11 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
",mmarked": "link:@types/,mmarked",
|
||||
"@astrojs/rss": "^2.4.3",
|
||||
"@types/marked": "^5.0.0",
|
||||
"astro": "^2.6.4",
|
||||
"astro-icon": "^0.8.1"
|
||||
"astro-icon": "^0.8.1",
|
||||
"marked": "^5.1.0"
|
||||
}
|
||||
}
|
||||
|
|
16
pnpm-lock.yaml
generated
16
pnpm-lock.yaml
generated
|
@ -1,14 +1,20 @@
|
|||
lockfileVersion: 5.4
|
||||
|
||||
specifiers:
|
||||
',mmarked': link:@types/,mmarked
|
||||
'@astrojs/rss': ^2.4.3
|
||||
'@types/marked': ^5.0.0
|
||||
astro: ^2.6.4
|
||||
astro-icon: ^0.8.1
|
||||
marked: ^5.1.0
|
||||
|
||||
dependencies:
|
||||
',mmarked': link:@types/,mmarked
|
||||
'@astrojs/rss': 2.4.3
|
||||
'@types/marked': 5.0.0
|
||||
astro: 2.6.4
|
||||
astro-icon: 0.8.1
|
||||
marked: 5.1.0
|
||||
|
||||
packages:
|
||||
|
||||
|
@ -672,6 +678,10 @@ packages:
|
|||
resolution: {integrity: sha512-sqm9g7mHlPY/43fcSNrCYfOeX9zkTTK+euO5E6+CVijSMm5tTjkVdwdqRkY3ljjIAf8679vps5jKUoJBCLsMDA==}
|
||||
dev: false
|
||||
|
||||
/@types/marked/5.0.0:
|
||||
resolution: {integrity: sha512-YcZe50jhltsCq7rc9MNZC/4QB/OnA2Pd6hrOSTOFajtabN+38slqgDDCeE/0F83SjkKBQcsZUj7VLWR0H5cKRA==}
|
||||
dev: false
|
||||
|
||||
/@types/mdast/3.0.11:
|
||||
resolution: {integrity: sha512-Y/uImid8aAwrEA24/1tcRZwpxX3pIFTSilcNDKSPn+Y2iDywSEachzRuvgAYYLR3wpGXAsMbv5lvKLDZLeYPAw==}
|
||||
dependencies:
|
||||
|
@ -1858,6 +1868,12 @@ packages:
|
|||
resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==}
|
||||
dev: false
|
||||
|
||||
/marked/5.1.0:
|
||||
resolution: {integrity: sha512-z3/nBe7aTI8JDszlYLk7dDVNpngjw0o1ZJtrA9kIfkkHcIF+xH7mO23aISl4WxP83elU+MFROgahqdpd05lMEQ==}
|
||||
engines: {node: '>= 18'}
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/mdast-util-definitions/5.1.2:
|
||||
resolution: {integrity: sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==}
|
||||
dependencies:
|
||||
|
|
Before Width: | Height: | Size: 402 B After Width: | Height: | Size: 402 B |
Before Width: | Height: | Size: 820 B After Width: | Height: | Size: 820 B |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
87
public/rss.xsl
Normal file
87
public/rss.xsl
Normal file
|
@ -0,0 +1,87 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsl:stylesheet
|
||||
version="3.0"
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:atom="http://www.w3.org/2005/Atom"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
|
||||
>
|
||||
<xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes" />
|
||||
<xsl:template match="/">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<link rel="icon" href="/images/logo.svg" />
|
||||
<style>
|
||||
:root {
|
||||
color-scheme: dark light;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "Lato", -apple-system, Roboto, "Helvetica Neue", Arial,
|
||||
"Noto Sans", sans-serif;
|
||||
margin: 0;
|
||||
background-attachment: fixed;
|
||||
background-image: url("/images/background.jpg");
|
||||
color: white;
|
||||
}
|
||||
|
||||
main {
|
||||
display: flex;
|
||||
gap: 3rem;
|
||||
height: 100vh;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
padding-bottom: 2rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
main > section {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
flex-direction: column;
|
||||
border-radius: 1rem;
|
||||
align-items: center;
|
||||
background: rgb(0 0 0 / 0.3);
|
||||
padding: 2rem;
|
||||
width: 90%;
|
||||
max-width: 40rem;
|
||||
transition: scale 0.2s;
|
||||
}
|
||||
|
||||
main > section > :is(h1, h2) {
|
||||
font-size: 2.5rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
main > section:hover {
|
||||
scale: 1.03;
|
||||
}
|
||||
|
||||
main > section > p {
|
||||
font-size: 1.5rem;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
max-width: 20rem;
|
||||
}
|
||||
|
||||
hr {
|
||||
width: 90%
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<section>
|
||||
<h1>RSS Feed</h1>
|
||||
<hr/>
|
||||
<p>
|
||||
Hello, this is my blog's RSS Feed. Copy the URL from
|
||||
the address bar, and add it to your RSS reader.
|
||||
</p>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
28
src/components/BlogPost.astro
Normal file
28
src/components/BlogPost.astro
Normal file
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
import styles from "../styles/BlogPost.module.css"
|
||||
import Divider from "../components/Divider.astro"
|
||||
|
||||
import type { CollectionEntry } from "astro:content"
|
||||
interface Props {
|
||||
post: CollectionEntry<"blog">
|
||||
}
|
||||
|
||||
const { data: post, render } = Astro.props.post
|
||||
const { Content } = await render()
|
||||
const pubDate = new Intl.DateTimeFormat("en-US", {
|
||||
month: "long",
|
||||
day: "numeric",
|
||||
year: "numeric"
|
||||
}).format(post.pubDate)
|
||||
---
|
||||
|
||||
<section class={styles.jumbo}>
|
||||
<span class={styles.date}>{pubDate}</span>
|
||||
<h2 class={styles.title}>
|
||||
{post.title}
|
||||
</h2>
|
||||
<Divider />
|
||||
<article class={styles.description}>
|
||||
<Content />
|
||||
</article>
|
||||
</section>
|
|
@ -7,7 +7,7 @@ import styles from "../styles/Top.module.css"
|
|||
<div class={styles.up} aria-hidden="true" id="up">
|
||||
<ButtonLink href="#"><Icon name="mdi:arrow-up" /></ButtonLink>
|
||||
|
||||
<script defer>
|
||||
<script>
|
||||
const up = document.querySelector("#up")
|
||||
document.addEventListener("scroll", () =>
|
||||
up.setAttribute("aria-hidden", window.scrollY == 0)
|
||||
|
|
6
src/content/blog/test copy 2.md
Normal file
6
src/content/blog/test copy 2.md
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
title: "Welcome to my blog!"
|
||||
pubDate: 1687027268667
|
||||
---
|
||||
|
||||
# **Test**
|
6
src/content/blog/test copy 3.md
Normal file
6
src/content/blog/test copy 3.md
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
title: "Welcome to my blog!"
|
||||
pubDate: 1687027268667
|
||||
---
|
||||
|
||||
# **Test**
|
6
src/content/blog/test copy 4.md
Normal file
6
src/content/blog/test copy 4.md
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
title: "Welcome to my blog!"
|
||||
pubDate: 1687027268667
|
||||
---
|
||||
|
||||
# **Test**
|
6
src/content/blog/test copy.md
Normal file
6
src/content/blog/test copy.md
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
title: "Welcome to my blog!"
|
||||
pubDate: 1687027268667
|
||||
---
|
||||
|
||||
# **Test**
|
6
src/content/blog/test.md
Normal file
6
src/content/blog/test.md
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
title: "Welcome to my blog!"
|
||||
pubDate: 1687027268667
|
||||
---
|
||||
|
||||
# **Test**
|
4
src/content/blog/welcome.md
Normal file
4
src/content/blog/welcome.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: "Welcome to my blog!"
|
||||
pubDate: 1687027268667
|
||||
---
|
|
@ -5,11 +5,10 @@ import Nav from "../components/Nav.astro"
|
|||
|
||||
export interface Props {
|
||||
page: string
|
||||
title?: string
|
||||
description: string
|
||||
}
|
||||
|
||||
const { page, title = page, description } = Astro.props
|
||||
const { page, description } = Astro.props
|
||||
---
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
@ -27,27 +26,27 @@ const { page, title = page, description } = Astro.props
|
|||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="32x32"
|
||||
href="/images/favicon-32x32.png"
|
||||
href="/favicon-32x32.png"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="16x16"
|
||||
href="/images/favicon-16x16.png"
|
||||
href="/favicon-16x16.png"
|
||||
/>
|
||||
<link rel="manifest" href="/site.webmanifest" />
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
<meta content={title} property="og:title" />
|
||||
<meta content={`Henry Hiles - ${page}`} property="og:title" />
|
||||
<meta content={description} property="og:description" />
|
||||
<meta content="/images/favicon.ico" property="og:image" />
|
||||
<meta content="/favicon.ico" property="og:image" />
|
||||
<meta content="#14bc9d" data-react-helmet="true" name="theme-color" />
|
||||
<title>Henry Hiles - {page}</title>
|
||||
</head>
|
||||
<body>
|
||||
<Nav />
|
||||
<main>
|
||||
<Nav />
|
||||
<slot />
|
||||
<Top />
|
||||
</main>
|
||||
<Top />
|
||||
</body>
|
||||
</html>
|
||||
|
|
20
src/pages/blog/[slug].astro
Normal file
20
src/pages/blog/[slug].astro
Normal file
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
import Layout from "../../layouts/Layout.astro"
|
||||
import { getCollection } from "astro:content"
|
||||
import BlogPost from "../../components/BlogPost.astro"
|
||||
export const getStaticPaths = async () => {
|
||||
const blogEntries = await getCollection("blog")
|
||||
|
||||
return blogEntries.map((post) => ({
|
||||
params: { slug: post.slug },
|
||||
props: { post }
|
||||
}))
|
||||
}
|
||||
|
||||
const { post } = Astro.props
|
||||
const { data } = post
|
||||
---
|
||||
|
||||
<Layout page={data.title} description={data.overview}>
|
||||
<BlogPost post={post} />
|
||||
</Layout>
|
62
src/pages/blog/index.astro
Normal file
62
src/pages/blog/index.astro
Normal file
|
@ -0,0 +1,62 @@
|
|||
---
|
||||
import Layout from "../../layouts/Layout.astro"
|
||||
import BlogPost from "../../components/BlogPost.astro"
|
||||
import styles from "../../styles/Blog.module.css"
|
||||
import { getCollection } from "astro:content"
|
||||
import Divider from "../../components/Divider.astro"
|
||||
|
||||
const posts = await getCollection("blog")
|
||||
---
|
||||
|
||||
<Layout page="Blog" description="The blog of Henry Hiles">
|
||||
<div class={styles.container}>
|
||||
<aside class={styles.sidebar}>
|
||||
<input type="text" placeholder="Search..." id="search" />
|
||||
</aside>
|
||||
<div class={styles.right}>
|
||||
<article class={styles.description}>
|
||||
<h1>Welcome to the blog!</h1>
|
||||
<Divider />
|
||||
<p>
|
||||
Hello, and welcome to my blog. I post about Discord Bot
|
||||
Development, Web Development, Linux, and other Tech-related
|
||||
subjects. You can filter and search in the sidebar.
|
||||
</p>
|
||||
</article>
|
||||
{
|
||||
posts.map((post) => (
|
||||
<a
|
||||
class={styles.link}
|
||||
href={`/blog/${post.slug}`}
|
||||
data-title={post.data.title}
|
||||
data-tags=""
|
||||
>
|
||||
<BlogPost post={post} />
|
||||
</a>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
|
||||
<script>
|
||||
const searchBar = document.querySelector("#search") as HTMLInputElement
|
||||
const posts = document.querySelectorAll(
|
||||
"[data-title]"
|
||||
) as NodeListOf<HTMLElement>
|
||||
|
||||
const search = () =>
|
||||
posts.forEach((post) =>
|
||||
post.setAttribute(
|
||||
"aria-hidden",
|
||||
post.dataset.title
|
||||
?.toLowerCase()
|
||||
?.includes(searchBar.value.toLowerCase())
|
||||
? "false"
|
||||
: "true"
|
||||
)
|
||||
)
|
||||
|
||||
searchBar?.addEventListener("input", search)
|
||||
addEventListener("load", search)
|
||||
</script>
|
24
src/pages/blog/rss.xml.js
Normal file
24
src/pages/blog/rss.xml.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
import rss from "@astrojs/rss"
|
||||
import { getCollection } from "astro:content"
|
||||
import { marked } from "marked"
|
||||
|
||||
export const get = async (context) => {
|
||||
const blog = await getCollection("blog")
|
||||
return rss({
|
||||
title: "Henry Hiles' Blog",
|
||||
description:
|
||||
"A blog about Linux, Web Development, Discord Bots, and more.",
|
||||
site: context.site,
|
||||
items: blog.map((post) => ({
|
||||
link: `/blog/${post.slug}/`,
|
||||
content: marked.parse(post.body, {
|
||||
mangle: false,
|
||||
headerIds: false
|
||||
}),
|
||||
...post.data
|
||||
})),
|
||||
customData: "<language>en-us</language>",
|
||||
trailingSlash: false,
|
||||
stylesheet: "/rss.xsl"
|
||||
})
|
||||
}
|
52
src/styles/Blog.module.css
Normal file
52
src/styles/Blog.module.css
Normal file
|
@ -0,0 +1,52 @@
|
|||
.link {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
color: unset;
|
||||
text-decoration: none;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.description {
|
||||
border: 2px solid var(--primary);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.description h1 {
|
||||
font-size: 2.8rem;
|
||||
margin: 1rem;
|
||||
}
|
||||
|
||||
.description p {
|
||||
font-size: 1.5rem;
|
||||
text-align: justify;
|
||||
max-width: 40rem;
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
gap: inherit;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
display: flex;
|
||||
position: sticky;
|
||||
top: 8rem;
|
||||
height: 80vh;
|
||||
flex-direction: column;
|
||||
width: 20rem;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
gap: 2rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
[aria-hidden="true"] {
|
||||
display: none;
|
||||
}
|
44
src/styles/BlogPost.module.css
Normal file
44
src/styles/BlogPost.module.css
Normal file
|
@ -0,0 +1,44 @@
|
|||
.jumbo {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.date {
|
||||
position: absolute;
|
||||
top: 1rem;
|
||||
right: 1rem;
|
||||
color: hsl(37 10% 58%);
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.8em;
|
||||
margin: 0.2em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.description p {
|
||||
font-size: 1.3rem;
|
||||
max-width: 40rem;
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
.description :is(h1, h2, h3) {
|
||||
text-align: center;
|
||||
margin: 1rem;
|
||||
}
|
||||
|
||||
.description h1 {
|
||||
font-size: 2.2rem;
|
||||
}
|
||||
|
||||
.description h2 {
|
||||
font-size: 1.6rem;
|
||||
}
|
||||
|
||||
.description :is(strong, em) {
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-align: justify;
|
||||
}
|
|
@ -2,9 +2,9 @@
|
|||
display: flex;
|
||||
background: rgb(0 0 0 / 0.1);
|
||||
border: 2px solid var(--primary);
|
||||
backdrop-filter: blur(20px);
|
||||
border-radius: 20px;
|
||||
padding: 20px;
|
||||
backdrop-filter: blur(2rem);
|
||||
border-radius: 2rem;
|
||||
padding: 2rem;
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
height: 100%;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
text-align: center;
|
||||
padding: 0;
|
||||
padding: 3rem 0 0;
|
||||
height: 100vh;
|
||||
height: 85vh;
|
||||
}
|
||||
|
||||
#jumbo i {
|
||||
|
|
|
@ -31,26 +31,28 @@ img {
|
|||
}
|
||||
|
||||
main {
|
||||
--gap: min(8vw, 4rem);
|
||||
display: flex;
|
||||
gap: 3rem;
|
||||
gap: var(--gap);
|
||||
padding: var(--gap);
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
padding-bottom: 2rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
main > section {
|
||||
:is(article, section, aside):not(section *, nav *, header *) {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-radius: 1rem;
|
||||
background: rgb(0 0 0 / 0.3);
|
||||
padding: 2rem;
|
||||
width: 90%;
|
||||
width: 100%;
|
||||
scroll-margin: 1rem;
|
||||
transition: scale 0.2s;
|
||||
}
|
||||
|
||||
main > section:hover {
|
||||
scale: 1.03;
|
||||
:is(article, section, aside):not(section *, nav *, header *):hover {
|
||||
scale: 102%;
|
||||
}
|
||||
|
||||
@media (min-width: 500px) {
|
||||
|
@ -66,3 +68,17 @@ a {
|
|||
a:not(:hover) {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
input[type="text"] {
|
||||
display: flex;
|
||||
background: rgb(0 0 0 / 0.1);
|
||||
border: 2px solid var(--primary);
|
||||
backdrop-filter: blur(2rem);
|
||||
border-radius: 1rem;
|
||||
padding: 1rem;
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
font-size: 1.5rem;
|
||||
color: white;
|
||||
justify-content: center;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue