Skip to content

Commit

Permalink
Implement Blog (#2)
Browse files Browse the repository at this point in the history
Implements `/blog/` and `/blog/[slug/` routes (no styling yet, so a lot of it is just dumping data in some form)
  • Loading branch information
Mitsunee authored May 29, 2021
1 parent ea6ca19 commit 2ef1567
Show file tree
Hide file tree
Showing 31 changed files with 450 additions and 59 deletions.
14 changes: 14 additions & 0 deletions assets/blog/posts/bread-falling-over.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
title: "Bread Falling Over"
description: "Wow! This Bread stands and then falls over! CONTENT!"
image: "/temp/bread-falling-over.jpg"
date: "7.1.2021"
youTubeVideo: "298gcJkdk2E"
tags: "Video, Things falling over"
---

Wow! Bread Falling over! **SUCH CONTENT**

this post tests image showing up despite `showImage` not being set.

Jan 7, 2021
15 changes: 15 additions & 0 deletions assets/blog/posts/do-re-mi-wurtz.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
title: "do re mi"
description: "Bill Wurtz' do re mi Video"
image: "/temp/do-re-mi.jpg"
showImage: true
date: "7.1.2016"
youTubeVideo: "4q1Zs3vbX8M"
tags: "Video, Music"
---

http://billwurtz.com

This post should just work because `showImage` is set to `true`

Jan 7, 2016
11 changes: 11 additions & 0 deletions assets/blog/posts/lorem-1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
title: "Lorem Ipsum Part 1"
description: "Lorem ipsum dolor sit amet"
image: "/assets/avi_small.jpg"
showImage: false
date: "29.5.2021 15:18 +2"
youTubeVideo: null
tags: "Testing, No Image, Lorem Ipsum"
---

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Morbi tristique senectus et netus et malesuada fames ac. Pretium aenean pharetra magna ac placerat vestibulum lectus mauris ultrices. Non arcu risus quis varius quam quisque id. A cras semper auctor neque vitae tempus quam. A arcu cursus vitae congue mauris rhoncus aenean vel elit. Morbi tristique senectus et netus et malesuada fames ac. Netus et malesuada fames ac turpis egestas maecenas pharetra convallis. Erat imperdiet sed euismod nisi porta. Tortor aliquam nulla facilisi cras fermentum. Vitae proin sagittis nisl rhoncus mattis rhoncus urna.
10 changes: 10 additions & 0 deletions assets/blog/posts/lorem-2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
title: "Lorem Ipsum Part 2"
description: "Enim facilisis gravida neque convallis a cras semper auctor"
image: "/assets/avi_small.jpg"
showImage: false
date: "29.5.2021 15:18 +2"
tags: "Testing, No Image, Lorem Ipsum"
---

Enim facilisis gravida neque convallis a cras semper auctor. Enim nunc faucibus a pellentesque sit. Ullamcorper dignissim cras tincidunt lobortis. Cras pulvinar mattis nunc sed. Mauris in aliquam sem fringilla ut. Porta lorem mollis aliquam ut porttitor leo a diam sollicitudin. Mi in nulla posuere sollicitudin aliquam ultrices sagittis orci. Dictum at tempor commodo ullamcorper a lacus vestibulum sed arcu. Magna etiam tempor orci eu lobortis. Magna etiam tempor orci eu lobortis. Proin nibh nisl condimentum id venenatis a condimentum vitae. Nisi quis eleifend quam adipiscing vitae.
12 changes: 12 additions & 0 deletions assets/blog/posts/lorem-3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
title: "Lorem Ipsum Part 3"
description: "Lectus magna fringilla urna porttitor rhoncus"
image: "/assets/avi_small.jpg"
showImage: false
date: "29.5.2021 15:18 +2"
tags: "Testing, No Image, Lorem Ipsum"
---

Lectus magna fringilla urna porttitor rhoncus. Fringilla phasellus faucibus scelerisque eleifend donec pretium vulputate sapien nec. Facilisis volutpat est velit egestas dui id ornare arcu. Magna eget est lorem ipsum dolor sit. Commodo ullamcorper a lacus vestibulum sed arcu non odio euismod. Neque sodales ut etiam sit amet nisl purus in. Posuere morbi leo urna molestie. Consectetur a erat nam at lectus urna duis convallis convallis. Quis auctor elit sed vulputate mi sit amet. Egestas egestas fringilla phasellus faucibus scelerisque eleifend donec pretium. Odio eu feugiat pretium nibh ipsum consequat nisl. Lorem dolor sed viverra ipsum nunc aliquet bibendum enim.

Venenatis tellus in metus vulputate eu scelerisque. Penatibus et magnis dis parturient montes. Commodo nulla facilisi nullam vehicula ipsum a arcu cursus. Quam pellentesque nec nam aliquam sem et tortor consequat. Urna id volutpat lacus laoreet non curabitur. Interdum varius sit amet mattis vulputate enim. Nunc vel risus commodo viverra maecenas. Donec enim diam vulputate ut. Tortor consequat id porta nibh venenatis cras sed felis. Imperdiet proin fermentum leo vel. Sit amet consectetur adipiscing elit. Diam volutpat commodo sed egestas egestas fringilla phasellus faucibus scelerisque. Consequat id porta nibh venenatis cras sed felis eget. Leo in vitae turpis massa sed elementum tempus egestas. Hac habitasse platea dictumst vestibulum rhoncus est. Vestibulum sed arcu non odio euismod lacinia. Tortor at auctor urna nunc id. Eget egestas purus viverra accumsan in nisl nisi scelerisque.
10 changes: 10 additions & 0 deletions assets/blog/posts/lorem-4.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
title: "Lorem Ipsum Part 4"
description: "Fermentum odio eu feugiat pretium nibh ipsum consequat nisl vel"
image: "/assets/avi_small.jpg"
showImage: false
date: "29.5.2021 15:18 +2"
tags: "Testing, No Image, Lorem Ipsum"
---

Fermentum odio eu feugiat pretium nibh ipsum consequat nisl vel. Sagittis nisl rhoncus mattis rhoncus urna neque viverra justo. Nisi vitae suscipit tellus mauris a diam. Nunc sed blandit libero volutpat sed cras ornare arcu. Bibendum neque egestas congue quisque egestas. Posuere morbi leo urna molestie. Egestas quis ipsum suspendisse ultrices gravida dictum fusce ut placerat. Odio pellentesque diam volutpat commodo sed egestas egestas. Leo integer malesuada nunc vel risus. Quam nulla porttitor massa id.
18 changes: 18 additions & 0 deletions assets/blog/posts/test-with-dashes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
title: "Test with Dashes in Filename"
description: "This blog post tests having dashes in the filename"
image: "/assets/avi_small.jpg"
showImage: false
date: "22.5.2021 17:26 +2"
youTubeVideo: null
tags: "Testing, No Image"
---

No Image should display above

| Test | Table | With Align Right |
| ---- | -------- | ---------------: |
| Test | Table | a |
| Row2 | of table | woof |

# Go [Home](/) but in an h1
9 changes: 7 additions & 2 deletions assets/blog/posts/test.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
---
title: "Test"
description: "I am testing my implementation of markdown for my blog"
description: "I am testing my implementation of markdown and prism for my blog"
image: "/assets/avi_small.jpg"
showImage: true
date: "19.5.2021 17:32 +2"
youTubeVideo: null
tags: "Testing, Image, Tag With Spaces In Name"
---

# Test
Image should display above

I **am** using [Next] with [Remark] and [Prism] :)

Expand Down
15 changes: 15 additions & 0 deletions assets/blog/posts/waffle-falling-over.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
title: "Waffle Falling Over"
description: "Wow! This Waffle stands and then falls over!!!"
image: "/temp/waffle-falling-over.jpg"
showImage: false
date: "14.8.2013"
youTubeVideo: "sDj72zqZakE"
tags: "Video, Things falling over"
---

Wow! This is a waffle falling over! **SUCH CONTENT**

This posts tests that the image shows up despite `showImage` being `false` by accident.

Aug 14, 2013
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
],
"scripts": {
"dev": "next dev",
"prebuild": "eslint ./components/**/*.js ./pages/**/*.js",
"prebuild": "eslint ./src/**/*.js ./pages/**/*.js",
"build": "next build",
"postbuild": "next export",
"start": "next start"
Expand Down Expand Up @@ -39,7 +39,7 @@
"remark": "^13.0.0",
"remark-html": "^13.0.1",
"remark-prism": "^1.3.6",
"spacetime": "^6.16.0",
"spacetime": "^6.16.1",
"zustand": "^3.5.1"
}
}
47 changes: 47 additions & 0 deletions pages/blog/[slug].js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import getPostList from "@utils/blog/getPostList";
import getPost from "@utils/blog/getPost";
import parsePost from "@utils/blog/parsePost";
import buildPostData from "@utils/blog/buildPostData";

import Meta from "@components/Meta";
import PostDate from "@components/blog/PostDate";

export default function BlogPost({ data, content }) {
// TODO: styling for header section for blog posts (title, date)
// TODO: styling for footer section for blog posts (tags, permalink)
// TODO: handle optional image and youtube video

return (
<>
<Meta
title={data.title}
description={data.description}
image={data.image}
route={`blog/${data.slug}`}
/>
<main>
<h1>{data.title}</h1>
<PostDate date={data.date} hasTime={data.hasTime} />
<div dangerouslySetInnerHTML={{ __html: content }} />
<h3>Tags (temp)</h3>
<p>{JSON.parse(data.tags).join(", ")}</p>
<p>
<a href={`/blog/${data.slug}/`}>Permalink</a>
</p>
</main>
</>
);
}

export async function getStaticPaths() {
const postList = await getPostList();
const paths = postList.map(({ slug }) => ({ params: { slug } }));
return { paths, fallback: false };
}

export async function getStaticProps({ params: { slug } }) {
const postRaw = await getPost(slug);
const { data: rawData, content } = await parsePost(postRaw);
const data = buildPostData(rawData, `${slug}.md`);
return { props: { data, content } };
}
74 changes: 74 additions & 0 deletions pages/blog/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { useState } from "react";
//import { stylesheet, css } from "astroturf";
import Link from "next/link";

import Meta from "@components/Meta";
import PostDate from "@components/blog/PostDate";
import getPostList from "@utils/blog/getPostList";
import filterUnique from "@utils/filter.unique";

function handleSearch(postList, searchQuery) {
if (searchQuery === "") return postList;
const sanitizedQuery = searchQuery.toLowerCase().replace(/[^a-z0-9 ]/g, "");
if (sanitizedQuery === "") return postList;
return postList
.filter(({ title }) => title.toLowerCase().includes(sanitizedQuery))
.sort(({ date: a }, { date: b }) => a - b);
}

export default function BlogIndex({ postList, tagList }) {
const [search, setSearch] = useState("");
const filteredList = handleSearch(postList, search);
return (
<>
<Meta
title={"Blog"}
description={"Mitsunee's Blog"}
// TODO: BlogIndex meta image
route={"blog"}
/>
<main>
<h1>POSTS</h1>
<input
type="text"
value={search}
placeholder={"Search"}
onChange={e => setSearch(e.target.value)}
/>
{filteredList.length > 0 ? (
<ul>
{filteredList.map(post => (
<li key={post.slug}>
<Link href={`/blog/${post.slug}/`}>
<a title={post.slug}>{post.title}</a>
</Link>
<ul>
<li>
<PostDate date={post.date} hasTime={post.hasTime} />
</li>
<li>{JSON.parse(post.tags).join(", ")}</li>
</ul>
</li>
))}
</ul>
) : (
<p>No Posts found for query {`"${search}"`}</p>
)}
<h2>Known Tags</h2>
<p>{tagList.join(", ")}</p>
</main>
</>
);
}

export async function getStaticProps() {
const postList = await getPostList();

// TODO: sort posts by date

const tagList = postList
.reduce((list, post) => list.concat(JSON.parse(post.tags)), [])
.filter(filterUnique)
.sort(); // sort alphabetically
return { props: { postList, tagList } };
}
12 changes: 4 additions & 8 deletions pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { stylesheet, css } from "astroturf";
import Link from "next/link";

import Meta from "@components/Meta";
import TestComponent from "@components/test/test";

// TEMP test astroturf-loader
const styles = stylesheet`
Expand All @@ -16,7 +15,7 @@ const styles = stylesheet`
}
`;

const Index = () => {
export default function Index() {
return (
<>
<Meta
Expand All @@ -38,13 +37,10 @@ const Index = () => {
`}>
I should be using the accent color via astroturf&#39;s css prop
</p>
<TestComponent />
<Link href="/test">
<a>Go to test</a>
<Link href="/blog">
<a>Go to blog</a>
</Link>
</main>
</>
);
};

export default Index;
}
24 changes: 0 additions & 24 deletions pages/test.js

This file was deleted.

Binary file added public/temp/bread-falling-over.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/temp/do-re-mi.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/temp/waffle-falling-over.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions src/components/blog/PostDate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import spacetime from "spacetime";

export default function PostDate({ date, hasTime, className }) {
const time = hasTime ? spacetime(date) : spacetime(date, "utc");
const dateTime = hasTime ? time.format("iso") : time.format("iso-short");
const timeText = hasTime
? time.format(
"{day}, {month} {date-ordinal} {year}, {hour-24}:{minute-pad}"
)
: time.format("{day}, {month} {date-ordinal} {year}");
return (
<time dateTime={dateTime} className={className}>
{timeText}
</time>
);
}
3 changes: 0 additions & 3 deletions src/components/test/test.js

This file was deleted.

30 changes: 30 additions & 0 deletions src/utils/blog/buildPostData.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import buildTags from "./helpers/buildTags";
import dateStringToUnix from "./helpers/dateStringToUnix";

const postDataDefaults = {
showImage: true,
youtubeVideo: null
};

// applies defaults, adds slug and turns tags into JSON Array (stringified)
export default function buildPostData(data, post) {
if (data === undefined || !post) {
console.log({ data, post });
throw new TypeError(`data is incomplete for ${post}`);
}

const slug = post.replace(/\.md$/, "");
const tags = buildTags(data.tags);
const date = dateStringToUnix(data.date);

// throw in case of unparsable date
if (date === false) throw new Error(`Could not convert date for ${post}`);

return {
...postDataDefaults, // default values for optional props showImage and youTubeVideo
...data, // parsed matter
...date, // contains props: date (as timestamp), hasTime
slug, // slug as string
tags // tags as stringified array
};
}
11 changes: 11 additions & 0 deletions src/utils/blog/getPost.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { readFileSync } from "fs";
import joinPath from "@utils/joinPath";

export default function getPost(filename) {
return readFileSync(
joinPath(
"assets/blog/posts",
filename.endsWith(".md") ? filename : `${filename}.md`
)
);
}
Loading

0 comments on commit 2ef1567

Please sign in to comment.