Write blog post on Astro

Fix some styling issues I found in Markdown
Remove need for a <hr> under the header, since I do that everywhere anyway I may as well just style it that way
This commit is contained in:
Michał 2024-05-29 14:45:33 +01:00
parent c39c794892
commit 3f59955d14
14 changed files with 226 additions and 55 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View file

@ -23,7 +23,7 @@ import leg from "../assets/leg.webp";
const request = await fetch("https://lastfm-last-played.biancarosa.com.br/Fluffy_Bean_/latest-song");
const data = await request.json();
( document.querySelector("#music-image") as HTMLImageElement ).src = data["track"]["image"][1]["#text"];
( document.querySelector("#music-image") as HTMLImageElement ).src = data["track"]["image"][2]["#text"];
( document.querySelector("#music-title") as HTMLParagraphElement ).innerText = `${data["track"]["name"]}`;
( document.querySelector("#music-artist") as HTMLParagraphElement ).innerText = `by ${data["track"]["artist"]["#text"]}`;
( document.querySelector("#music-album") as HTMLParagraphElement ).innerText = `on ${data["track"]["album"]["#text"]}`;

View file

@ -1,12 +1,13 @@
---
title: Hello, Django!
description: Imported blog from old website
description: Django is fun!
pubDate: 2023-06-19
tags:
- python
- django
- caddy
- networking
- webdev
---
import Note from "../../components/Note.astro";

View file

@ -5,6 +5,7 @@ pubDate: 2024-05-28
tags:
- astro
- typescript
- webdev
---
Hello! Welcome to my new website, or at least as of writing this blog.
@ -15,20 +16,106 @@ So where do I start, maybe _why_ I have chosen Astro over other existing options
## Why Astro
TLDR: I don't know :3
- I've been trying to learn typescript through trying astro
- Astro is hard, due to all the issues I've encountered
I've been trying to learn Typescript for about a month now, mainly to broaden my skill set, but to also help me with job
searching. Firstly through Svelte for a college project (which I may write about), but now Astro.
I've chosen Astro for two main reasons
1. It's statically compiled, meaning that I don't ship any smelly Javascript to the browser, which I detest doing when not needed
2. It looked simple enough compared to other options
So, what was the experience like so far you may be asking, ehh...
## The problems
- Issue with Astros `getEntries()` not working, thus having to implement my own method
- Fighting with Astro to display banner images, it won
- Using external plugins for images/slides
- Specifically passing variables into scripts
### `Image` and `Picture`
The first and biggest hurdle I faced was the `Image` and `Picture` elements from Astro. I could not for the life of me,
figure out a good solution for using both a file path, and a URL for the `frontmatter` data. I tried:
- `getImage()`
- Checking if the start of the string begins with `https://`
- Loading the image using `getImage()` on every page that passed the image data into the `Layout.astro` to set as the banner image
**NOTHING FUCKING WORKED.**
I spent a good few hours trying to get that working, until I came across the `image()` schema helper. I followed the
documentation, I followed videos, I copied code from existing repositories, nothing worked, it refused to load images
by file path, instead returning a string every time...
So I simply gave up, and I think that's for the best considering I want to keep my hair, and I had better things todo.
You win Astro, you win.
### PhotoSwipe
When working on the Refsheet part of this website, I wanted to use a library to be able to view images fullscreen. Maybe
I'm stupid, maybe I'm dumb, but I could not get [PhotoSwipe](https://photoswipe.com/) to work, at least when using
multiple sets of images on a page.
I tried stupid things such as creating unique IDs for each gallery element, but when
passing them into a `<script>` tag, it would break imports, as passing Astro variables into these for use on the user
side, it would put them _above_ the `import`s.
I know I'll figure this out, as I've already created a `plugins` section for my Layout, that looks as such.
```astro
---
// Layout.astro
interface Props {
title: string;
plugins?: {
katex?: boolean,
}
seo?: {
description?: string,
tags?: string[],
}
}
const { title, plugins, seo } = Astro.props;
---
<!doctype html>
<html lang="en">
<head>
<title>{title}</title>
{plugins?.katex && (
<!-- Import Katex here -->
)}
</head>
<body>
<p>Balls</p>
</body>
</html>
```
```astro
---
// Markdown.astro
import Layout from "./Layout.astro";
// Get post data here
---
<Layout
plugins={{
katex: true,
}}
>
```
So I know it's possible...
### Broken `getEntries()`...
My last gripe I had with Astro was the broken `getEntries()` function, while it made it annoying to not get tag data for
posts, it wasn't hard to implement myself for the use of this blog. It's not that well optimised in my option, but it
does what it needs todo and doesn't run in the users browser anyway, thanks Astro.
```typescript
export async function getTagsBySlug(
postTags: string[],
): Promise<CollectionEntry<"tags">[]> {
// Collect all the tags from collections
// utils.ts
export async function getTagsBySlug(postTags: string[]): Promise<CollectionEntry<"tags">[]> {
const allTags: CollectionEntry<"tags">[] = await getCollection("tags");
// Loop through all the tags in a post and the tags in the collections
@ -46,6 +133,22 @@ export async function getTagsBySlug(
```
## What I've learned
- More experience writing in Typescript
- Learning about MDX accidentally
- Reading Documentation, ironically
While Astro was a meh experience, I doubt all the problems I encountered where an Astro issue, most where probably a
skill issue tbh.
That said, trial by error (or fire when doing JavaScript/TypeScript) is a good way to learn, so I did learn much indeed,
both on Astro and TypeScript.
Other things I wasn't expecting to learn on the way was digging through Documentation more thoroughly and trying MDX. So
that's a win!
## Final words
I'm hoping to write more blogs in the future, mainly to practice my writing skills, and sharing my options publicly,
regardless if it's something political or programming related. But life's in a tangle right now
<div style="width: 200px">
![Maned Wolf art by Pulex](../../assets/posts/pulex_leg.webp)
[Art by Pulex](https://www.pulexart.com/)
</div>

View file

@ -0,0 +1,3 @@
---
name: Web Development
---

View file

@ -13,7 +13,7 @@ interface Props {
}
}
const { title, plugins, seo} = Astro.props;
const { title, plugins, seo } = Astro.props;
---
<!doctype html>

View file

@ -36,6 +36,7 @@ const tags = await getTagsBySlug(post.data.tags);
<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>
<!-- Sticky could be added, but it makes it a buit difficult to read things on mobile-->
<div class="header">
<h1>{post.data.title}</h1>
{post.data.pubDate ? (
@ -47,7 +48,7 @@ const tags = await getTagsBySlug(post.data.tags);
{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>
<!--<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>
@ -55,9 +56,11 @@ const tags = await getTagsBySlug(post.data.tags);
</ul>
</div>
<hr>
{post.data.base}
<!--<div class="header-follow">-->
<!-- <div>-->
<!-- <p>GwaGwa</p>-->
<!-- </div>-->
<!--</div>-->
<div id="markdown">
<div style="margin-bottom: 32px" />
@ -124,20 +127,6 @@ const tags = await getTagsBySlug(post.data.tags);
}
}
/*#source {*/
/* position: absolute;*/
/* top: 16px;*/
/* right: 16px;*/
/* text-decoration: none;*/
/* color: $accent;*/
/* &:hover, &:focus-visible {*/
/* text-decoration: underline;*/
/* }*/
/*}*/
#controls {
display: flex;
flex-direction: row;
@ -196,6 +185,7 @@ const tags = await getTagsBySlug(post.data.tags);
}
ol, ul {
margin: 16px 0;
padding-left: 32px;
}
@ -228,7 +218,7 @@ const tags = await getTagsBySlug(post.data.tags);
}
table {
margin: 16px 0;
margin: 16px -16px;
width: 100%;
@ -275,6 +265,8 @@ const tags = await getTagsBySlug(post.data.tags);
}
img {
margin: 16px -16px;
max-width: 100%;
height: auto;
@ -282,7 +274,7 @@ const tags = await getTagsBySlug(post.data.tags);
}
.astro-code {
margin: 16px 0;
margin: 20px -16px;
padding: 40px 8px 8px;

View file

@ -21,8 +21,6 @@ const posts = await getPosts("posts");
<Music />
</div>
<hr>
<div class="section">
<h2>Who am I</h2>
<p>My name is Michał, I go by Fluffy, I'm 19 and I like computers</p>

View file

@ -12,8 +12,6 @@ import GwaGwa from "../assets/fumble.jpg";
<p>GwaGwa</p>
</div>
<hr>
<img
src={GwaGwa.src}
alt="Two Maned wolfs having a disagreement"

View file

@ -20,8 +20,6 @@ const posts = await getPosts("posts");
<p>Books of egg</p>
</div>
<hr>
<ul role="list" class="project-list">
{posts.map(post => (
<Card {post}/>

View file

@ -30,14 +30,11 @@ const filteredPosts = allPosts.filter((project) => project.data.tags.includes(ta
<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 => (

View file

@ -7,11 +7,17 @@ import HomeButton from "../../components/HomeButton.astro";
const tags = await getCollection("tags");
const posts = await getPosts("posts");
// Get post count for reach tag
tags.forEach((tag) => {
tag.data.postCount = posts.filter((project) => {
return project.data.tags.includes(tag.slug);
}).length;
})
// Dunno if Astro auto-sorts stuff
tags.sort((a, b) => {
return a.data.name.localeCompare(b.data.name);
});
---
<Layout title="Leggy Land - All Projects">
@ -22,16 +28,37 @@ tags.forEach((tag) => {
<p>Filter posts by tags</p>
</div>
<hr>
<ul role="list" class="pill-list">
{tags.map(tag => (
<li>
<a class="pill large" href=`/search/${tag.slug}`>
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" 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} - {tag.data.postCount}
<!--<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" 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} <span class="blob">{tag.data.postCount}</span>
</a>
</li>
))}
</ul>
</Layout>
<style lang="scss">
@import "../../styles/vars.scss";
.blob {
margin-left: 8px;
min-width: 18px;
height: 18px;
display: flex;
justify-content: center;
align-items: center;
font-weight: 600;
font-size: 12px;
font-family: $font-mono;
border-radius: 9999px;
background-color: $accent;
color: $light;
}
</style>

View file

@ -1,9 +1,49 @@
.header {
margin: -32px -32px 32px;
padding: 32px;
display: flex;
flex-direction: column;
gap: 16px;
border-bottom: 2px solid $gray;
background-color: $dark;
z-index: 999;
> h1 {
margin-bottom: calc((16px - 4px) * -1);
}
&.sticky {
position: sticky;
top: 0;
}
}
.header-follow {
margin: calc(-32px - 50px + 2px) 0 0;
height: 0;
position: sticky;
top: 0;
> div {
padding: 0 32px;
width: calc(100% + 64px);
height: 50px;
position: absolute;
left: -32px;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
border-bottom: 2px solid $gray;
background-color: $dark;
color: $light;
}
}

View file

@ -1,15 +1,18 @@
#music {
padding: 16px;
padding: 20px;
width: unset;
height: unset;
position: relative;
display: flex;
flex-direction: row;
justify-content: unset;
align-items: unset;
text-decoration: none;
font-size: 16px;
border-radius: $radius;
@ -18,20 +21,31 @@
}
> img {
margin-right: 16px;
width: auto;
height: 100%;
width: 64px;
height: 64px;
position: absolute;
top: 0;
left: 0;
border-radius: $radius;
//border-radius: $radius;
mask-image: linear-gradient(to right, rgba(#fff, 0.5), rgba(#fff, 0) 80%);
object-fit: cover;
z-index: +1;
}
> ul {
position: relative;
display: flex;
flex-direction: column;
justify-content: flex-start;
gap: 4px;
z-index: +2;
> li {
font-size: 16px;
list-style: none;
}
}