changed from hexo to custom react stuff #1

Merged
developomp merged 73 commits from dev into master 2021-06-27 14:37:56 +09:00
44 changed files with 329 additions and 221 deletions
Showing only changes of commit e907b9009f - Show all commits

3
.gitignore vendored
View file

@ -4,7 +4,8 @@ _/
# auto generated files # auto generated files
yarn.lock yarn.lock
package-lock.json package-lock.json
pages.json posts.json
posts/
# dependencies # dependencies
.pnp/ .pnp/

View file

@ -1,82 +1,166 @@
/** /**
* It reads markdown files and write its content and metadata to a json file that can be used by React. * It reads markdown files and write its content and metadata to json files that can be imported by React.
* - Files and directories names starting with a underscore (_ <- this thing), will be ignored * - Files and directories names starting with a underscore (_) will be ignored
* - Symbolic links are also be ignored as of the moment * - Symbolic links are ignored as of the moment
* - Filename-to-url encoder not perfect. Some filenames might cause problem (like files containing special characters) * - Filename-to-url encoder is not perfect. Some non-url-friendly filenames might cause problems
*/ */
import fs from "fs" // read and write files import fs from "fs" // read and write files
import path from "path" // get relative path import path from "path" // get relative path
import matter from "gray-matter" // parse markdown metadata import matter from "gray-matter" // parse markdown metadata
// import createDOMPurify from "dompurify" // sanitize result html
// import { JSDOM } from "jsdom" // create empty window for fom purifier to work. Morea info here: https://github.com/cure53/DOMPurify
import toc from "markdown-toc" // table of contents generation import toc from "markdown-toc" // table of contents generation
// const window = new JSDOM("").window
// const DOMPurify = createDOMPurify(window)
const dirPath = "./markdown" // where it will look for markdown documents const dirPath = "./markdown" // where it will look for markdown documents
const outPath = "./src/pages.json" // path to the json database const outPath = "./src/data" // path to the json database
const removeExceptionArray = ["content", "meta"] // gray-matter creates unnecessary properties // data that will be converted to JSON string
const result = {
date: {},
tags: {},
posts: {},
}
const pageList = {} // data that will be converted to JSON string // creates directory/directories
// https://stackoverflow.com/a/40686946/12979111
function mkDirByPathSync(targetDir, { isRelativeToScript = false } = {}) {
const sep = path.sep
const initDir = path.isAbsolute(targetDir) ? sep : ""
const baseDir = isRelativeToScript ? __dirname : "."
return targetDir.split(sep).reduce((parentDir, childDir) => {
const curDir = path.resolve(baseDir, parentDir, childDir)
try {
fs.mkdirSync(curDir)
} catch (err) {
if (err.code === "EEXIST") {
// curDir already exists!
return curDir
}
// To avoid `EISDIR` error on Mac and `EACCES`-->`ENOENT` and `EPERM` on Windows.
if (err.code === "ENOENT") {
// Throw the original parentDir error on curDir `ENOENT` failure.
throw new Error(
`EACCES: permission denied, mkdir '${parentDir}'`
)
}
const caughtErr =
["EACCES", "EPERM", "EISDIR"].indexOf(err.code) > -1
if (
!caughtErr ||
(caughtErr && curDir === path.resolve(targetDir))
) {
throw err // Throw if it's just the last created dir.
}
}
return curDir
}, initDir)
}
// big brain recursive function
// only supports folders and files (no symbolic links) // only supports folders and files (no symbolic links)
// does not scale well for large amount of folders and files // does not scale well for large number of folders
function addFiles(filesPath: string) { // it calls itself for every directory it finds
function recursiveParser(fileOrFolderPath: string) {
// ignore if file/directory name starts with a underscore // ignore if file/directory name starts with a underscore
const fileOrFolderName = filesPath.substring(filesPath.lastIndexOf("/") + 1) const fileOrFolderName = fileOrFolderPath.substring(
fileOrFolderPath.lastIndexOf("/") + 1
)
if (fileOrFolderName.startsWith("_")) return if (fileOrFolderName.startsWith("_")) return
// not perfect. Some filenames might cause problem. // not perfect. Some filenames might cause problems.
const stats = fs.lstatSync(filesPath) // checks if the path leads to a directory or a file const stats = fs.lstatSync(fileOrFolderPath) // checks if the path leads to a directory or a file
// don't use replaceAll // don't use replaceAll
const urlPath = `/${path.relative(dirPath, filesPath)}` // path tha will be used for url const urlPath = `/${path.relative(dirPath, fileOrFolderPath)}` // path that will be used as site url
.replace(/\.[^/.]+$/, "") // remove .md file extension .replace(/\.[^/.]+$/, "") // remove file extension
.replace(/ /g, "-") // replace space with a dash "-" .replace(/ /g, "-") // replace space with a dash "-"
// if it's a directory, apply this function to every files/folders in it // if it's a directory, apply this function to every files/folders in it
// if it's a file, read and add it to pageList // if it's a file, parse and save it to file
if (stats.isDirectory()) { if (stats.isDirectory()) {
fs.readdirSync(filesPath).map((child) => fs.readdirSync(fileOrFolderPath).map((child) =>
addFiles(`${filesPath}/${child}`) recursiveParser(`${fileOrFolderPath}/${child}`)
) )
} else if (stats.isFile()) { } else if (stats.isFile()) {
// skip if file is not a markdown file // skip if file is not a markdown file
if (!fileOrFolderName.endsWith(".md")) { if (!fileOrFolderName.endsWith(".md")) {
console.log(`Ignoring non markdown file at: ${filesPath}`) console.log(`Ignoring non markdown file at: ${fileOrFolderPath}`)
return return
} }
pageList[urlPath] = matter(fs.readFileSync(filesPath, "utf8")) // parse markdown metadata const parsedMarkdown = matter(fs.readFileSync(fileOrFolderPath, "utf8")) // parse markdown metadata
const contentJSONFile = `${outPath}/posts${urlPath}.json`
// sanitizing should happens here but this code removes blockquote for some reason mkDirByPathSync(
// I might have to take a look at https://github.com/cure53/DOMPurify/issues/186 later contentJSONFile.substring(0, contentJSONFile.lastIndexOf("/") + 1)
// pageList[urlPath].content = DOMPurify.sanitize(
// pageList[urlPath].content
// )
pageList[urlPath].meta = pageList[urlPath].data // change property name from data to meta
pageList[urlPath].meta.toc = toc(pageList[urlPath].content).content
// removes unnecessary data
Object.keys(pageList[urlPath]).forEach(
(key) =>
removeExceptionArray.includes(key) ||
delete pageList[urlPath][key]
) )
// write content to json file
fs.writeFileSync(
contentJSONFile,
JSON.stringify({
content: parsedMarkdown.content,
})
)
result.posts[urlPath] = parsedMarkdown.data
// date
if (!result.posts[urlPath].date) {
throw Error(`Date does not exist in file: ${urlPath}`)
}
result.posts[urlPath].date = new Date(
parsedMarkdown.data.date
).toLocaleString("default", {
month: "short",
day: "numeric",
year: "numeric",
})
if (result.date[result.posts[urlPath].date])
result.date[result.posts[urlPath].date].push(urlPath)
else result.date[result.posts[urlPath].date] = [urlPath]
//tags
if (result.posts[urlPath].tags) {
result.posts[urlPath].tags.forEach((tag) => {
if (result.tags[tag]) result.tags[tag].push(urlPath)
else result.tags[tag] = [urlPath]
})
}
// toc
result.posts[urlPath].toc = toc(result.posts[urlPath].content).content
} }
} }
// start recursive function + check if it's a directory /** Step 1
* Deleting existing files
*/
try {
fs.rmSync(`${outPath}/posts`, { recursive: true })
// eslint-disable-next-line no-empty
} catch (err) {}
try {
fs.unlinkSync(`${outPath}/posts.json`)
// eslint-disable-next-line no-empty
} catch (err) {}
/** Step 2
* Populate result and write to src/data/posts/
*/
// check if it's a directory and start recursive function
if (fs.lstatSync(dirPath).isDirectory()) { if (fs.lstatSync(dirPath).isDirectory()) {
addFiles(dirPath) recursiveParser(dirPath)
} else { } else {
console.log("Path is not a directory. Result file will be empty.") throw Error("Initial path given does not lead to a directory")
} }
// write to json file /** Step 3
fs.writeFileSync(outPath, JSON.stringify(pageList) + "\n") * write to src/data/posts.json
*/
fs.writeFileSync(`${outPath}/posts.json`, JSON.stringify(result) + "\n")

View file

@ -1,10 +0,0 @@
---
title:
comment:
licenses:
widgets:
article:
author:
---
Put something here

View file

@ -1,6 +1,5 @@
--- ---
title: About title: About
author: developomp
date: April 20, 2021 date: April 20, 2021
--- ---

View file

@ -1,7 +1,6 @@
--- ---
title: games title: games
date: Aug 16, 2020 date: Aug 16, 2020
author: developomp
--- ---
- [TicTacToe](/games/tictactoe) - [TicTacToe](/games/tictactoe)

View file

@ -1,7 +1,6 @@
--- ---
title: goals title: goals
date: May 11, 2021 date: 2021-05-11
author: developomp
--- ---
- skill - skill

View file

@ -1,8 +1,8 @@
--- ---
title: Quote NO.1 title: Quote NO.1
date: Aug 16, 2020 date: Aug 16, 2020
tags: quotes tags:
author: developomp - quotes
--- ---
> "Get the fuck out of my lawn" > "Get the fuck out of my lawn"

View file

@ -1,8 +1,8 @@
--- ---
title: Quote NO.2 title: Quote NO.2
date: Feb 20, 2021 date: Feb 20, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
In a Q&A session in Aalto Talk with Linus Torvalds, hosted by Aalto Center for Entrepreneurship (ACE) in Otaniemi. In a Q&A session in Aalto Talk with Linus Torvalds, hosted by Aalto Center for Entrepreneurship (ACE) in Otaniemi.

View file

@ -1,8 +1,8 @@
--- ---
title: Quote NO.3 title: Quote NO.3
date: March 18, 2021 date: March 18, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
In the introduction of one of his book: "The Future of the mind" (9th paragraph) In the introduction of one of his book: "The Future of the mind" (9th paragraph)

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.1 title: My Quote NO.1
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> Let's find problems in ourselves first > Let's find problems in ourselves first

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.10 title: My Quote NO.10
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> Don't forget what you planned to be > Don't forget what you planned to be

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.11 title: My Quote NO.11
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> Yesterday is a lecture for today > Yesterday is a lecture for today

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.12 title: My Quote NO.12
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> Practice isn't a action. Its a formation. > Practice isn't a action. Its a formation.

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.13 title: My Quote NO.13
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> Don't forget the peaks and the valleys of your life. > Don't forget the peaks and the valleys of your life.

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.14 title: My Quote NO.14
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> Those who see only the present lose their future.<br /> > Those who see only the present lose their future.<br />

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.15 title: My Quote NO.15
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> The depth of a proverb is proportional to the depth of the reader's thoughts. > The depth of a proverb is proportional to the depth of the reader's thoughts.

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.16 title: My Quote NO.16
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> Words of wisdom deepens the more you think about it. > Words of wisdom deepens the more you think about it.

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.17 title: My Quote NO.17
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> God didn't bless us with the best, so let's do it ourself. > God didn't bless us with the best, so let's do it ourself.

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.18 title: My Quote NO.18
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> I got a purpose now, so why sit down?<br> > I got a purpose now, so why sit down?<br>

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.19 title: My Quote NO.19
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> Finding the problem is the first step to solving anything > Finding the problem is the first step to solving anything

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.2 title: My Quote NO.2
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> Don't be great for your fame, but be famous for your greatness. > Don't be great for your fame, but be famous for your greatness.

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.20 title: My Quote NO.20
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> Look at the clock and wait for the next minute to come.<br> > Look at the clock and wait for the next minute to come.<br>

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.21 title: My Quote NO.21
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> Kill an ant. Throw it and try to find it.<br> > Kill an ant. Throw it and try to find it.<br>

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.22 title: My Quote NO.22
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> Lot of things learned, nothing useful. > Lot of things learned, nothing useful.

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.23 title: My Quote NO.23
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> To give 10, one should know a 100. > To give 10, one should know a 100.

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.24 title: My Quote NO.24
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> Think about everything > Think about everything

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.25 title: My Quote NO.25
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> Challenge yourself to give your best at all time. > Challenge yourself to give your best at all time.

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.26 title: My Quote NO.26
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> Escape from the valleys of life doesn't happen in an instant. > Escape from the valleys of life doesn't happen in an instant.

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.27 title: My Quote NO.27
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> Sometimes I am amazed by the fact that I am aware of anything. > Sometimes I am amazed by the fact that I am aware of anything.

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.28 title: My Quote NO.28
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> Mind is like a sword. It will be dull if you stop sharpening it. > Mind is like a sword. It will be dull if you stop sharpening it.

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.29 title: My Quote NO.29
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> Even if the day comes when we can live for hundreds of years, we'll still make a world where hard working is a necessity. > Even if the day comes when we can live for hundreds of years, we'll still make a world where hard working is a necessity.

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.3 title: My Quote NO.3
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> If you have a proverbs, record it. Treat it as if it's a jewel. In the future, this fine gem will be the eyes of many, and a lamp to light the ways of people. > If you have a proverbs, record it. Treat it as if it's a jewel. In the future, this fine gem will be the eyes of many, and a lamp to light the ways of people.

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.30 title: My Quote NO.30
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> If you think too much about the answer, you'll forget what the question was. > If you think too much about the answer, you'll forget what the question was.

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.31 title: My Quote NO.31
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> People earns highest respect from me are those who appreciate critiques. > People earns highest respect from me are those who appreciate critiques.

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.32 title: My Quote NO.32
date: May 10, 2021 date: May 10, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> Any field is fascinating as long as there are no exams. > Any field is fascinating as long as there are no exams.

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.4 title: My Quote NO.4
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> I don't want to call it learning that I didn't learn with my heart when I learn. > I don't want to call it learning that I didn't learn with my heart when I learn.

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.5 title: My Quote NO.5
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> Don't define anything different from normality as a failure. > Don't define anything different from normality as a failure.

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.6 title: My Quote NO.6
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> What did you do when everyone in the world ran? > What did you do when everyone in the world ran?

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.7 title: My Quote NO.7
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> The 1000 miles you've walked so far are not important. What's important is > The 1000 miles you've walked so far are not important. What's important is

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.8 title: My Quote NO.8
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> Out of all the thing you've done and haven't done, which one do you regret more? > Out of all the thing you've done and haven't done, which one do you regret more?

View file

@ -1,8 +1,8 @@
--- ---
title: My Quote NO.9 title: My Quote NO.9
date: March 22, 2021 date: March 22, 2021
tags: quotes tags:
author: developomp - quotes
--- ---
> People who don't know what they're talking about are the poorest people in the world. > People who don't know what they're talking about are the poorest people in the world.

View file

@ -26,7 +26,6 @@
"@testing-library/jest-dom": "^5.12.0", "@testing-library/jest-dom": "^5.12.0",
"@testing-library/react": "^11.2.7", "@testing-library/react": "^11.2.7",
"@testing-library/user-event": "^13.1.9", "@testing-library/user-event": "^13.1.9",
"dompurify": "^2.2.8",
"gray-matter": "^4.0.3", "gray-matter": "^4.0.3",
"local-storage-fallback": "^4.1.2", "local-storage-fallback": "^4.1.2",
"markdown-toc": "^1.2.0", "markdown-toc": "^1.2.0",

View file

@ -2,83 +2,107 @@ import React from "react"
import marked from "marked" import marked from "marked"
import { Helmet } from "react-helmet-async" import { Helmet } from "react-helmet-async"
import pages from "../pages.json" import posts from "../data/posts.json"
import NotFound from "./NotFound" import NotFound from "./NotFound"
import Spinner from "../components/Spinner"
export default class Page extends React.Component { interface PageProps {}
interface PageState {
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
fetched: any fetchedPage: any
loading: boolean
}
export default class Page extends React.Component<PageProps, PageState> {
constructor(props) { constructor(props) {
super(props) super(props)
this.state = {
fetchedPage: undefined,
loading: true,
}
}
const fetched = pages[location.pathname.replace(/\/$/, "")] // remove a trailing slash async componentDidMount() {
if (!fetched) return const url = location.pathname.replace(/\/$/, "")
const fetchedPage = posts.posts[url] // remove a trailing slash
fetched.content = fetched?.content ? fetched.content : "No content" if (!fetchedPage) {
fetched.toc = fetched.meta?.toc ? fetched.meta.toc : undefined this.setState({
fetched.title = fetched.meta?.title ? fetched.meta.title : "No title" loading: false,
fetched.date = fetched.meta?.date ? fetched.meta.date : "Unknown date" })
fetched.author = fetched.meta?.author return
? fetched.meta.author }
: "Unknown author"
this.fetched = fetched const fetched_content = (await import(`../data/posts${url}.json`))
.content
fetchedPage.content = fetched_content ? fetched_content : "No content"
fetchedPage.toc = fetchedPage?.toc ? fetchedPage.toc : undefined
fetchedPage.title = fetchedPage?.title ? fetchedPage.title : "No title"
fetchedPage.date = fetchedPage?.date ? fetchedPage.date : "Unknown date"
this.setState({
fetchedPage: fetchedPage,
loading: false,
})
} }
render() { render() {
if (!this.fetched) return <NotFound /> if (this.state.loading) {
return <Spinner size={200} />
} else {
if (!this.state.fetchedPage) return <NotFound />
return ( return (
<> <>
<Helmet> <Helmet>
<title>pomp | {this.fetched.title}</title> <title>pomp | {this.state.fetchedPage.title}</title>
<meta property="og:title" content="Page Not Found" /> <meta
<meta property="og:type" content="website" /> property="og:title"
<meta property="og:url" content="http://developomp.com" /> content={this.state.fetchedPage.title}
<meta />
property="og:image" <meta property="og:type" content="website" />
content="http://developomp.com/icon/icon.svg" <meta
/> property="og:image"
<meta content={`${process.env.PUBLIC_URL}/icon/icon.svg`}
property="og:description" />
content="Page does not exist" </Helmet>
/> <div className="card main-content">
</Helmet> <h2>{this.state.fetchedPage.title}</h2>
<small>
<div className="card main-content"> Published on {this.state.fetchedPage.date} by
<h2>{this.fetched.title}</h2> developomp
<small> </small>
Published on {this.fetched.date} by{" "} <hr />
{this.fetched.author} {
</small> this.state.fetchedPage.toc && (
<hr /> <>
{ <div className="card">
this.fetched.toc && ( <strong>Table of Content:</strong>
<> <div
<div className="card"> className="link-color"
<strong>Table of Content:</strong> dangerouslySetInnerHTML={{
<div __html: marked(
className="link-color" this.state.fetchedPage.toc
dangerouslySetInnerHTML={{ ),
__html: marked(this.fetched.toc), }}
}} ></div>
></div> </div>
</div> <hr />
<hr /> </>
</> ) // add toc if it exists
) // add toc if it exists }
} <div
<div className="link-color"
className="link-color" dangerouslySetInnerHTML={{
dangerouslySetInnerHTML={{ __html: marked(this.state.fetchedPage.content),
__html: marked(this.fetched.content), }}
}} ></div>
></div> </div>
</div> </>
</> )
) }
} }
} }

View file

@ -5,7 +5,7 @@ import marked from "marked"
import { Helmet } from "react-helmet-async" import { Helmet } from "react-helmet-async"
import theming from "../theming" import theming from "../theming"
import pages from "../pages.json" import posts from "../data/posts.json"
const StyledPostList = styled.div` const StyledPostList = styled.div`
padding-top: 2rem; padding-top: 2rem;
@ -50,62 +50,77 @@ const StyledPostCard = styled.div`
padding: 10px 20px; padding: 10px 20px;
` `
interface HomeProps { interface PostListProps {
title: string title: string
howMany?: number howMany?: number
} }
export default class PostList extends React.Component<HomeProps> { interface PostListState {
howMany: number
isLimited: boolean
h1Text: string h1Text: string
PostCards: Array<unknown> = [] PostCards: Array<unknown>
}
export default class PostList extends React.Component<
PostListProps,
PostListState
> {
constructor(props) { constructor(props) {
super(props) super(props)
let howMany = props.howMany | 0 const howMany = props.howMany | 0
const isLimited = howMany ? true : false const isLimited = howMany ? true : false
const h1Text = isLimited ? `${howMany} recent posts` : "All posts"
this.h1Text = isLimited ? `${howMany} recent posts` : "All posts" this.state = {
howMany: howMany,
isLimited: isLimited,
h1Text: h1Text,
PostCards: [],
}
}
for (const pagePath in pages) { async componentDidMount() {
if (isLimited && howMany <= 0) continue const PostCards: Array<unknown> = []
let howMany = this.state.howMany
const post = pages[pagePath] for (const postPath in posts.posts) {
if (this.state.isLimited && howMany <= 0) continue
const data = await import(`../data/posts${postPath}.json`)
this.PostCards.push( const post = posts.posts[postPath]
<StyledPostCard key={pagePath} className="card main-content">
PostCards.push(
<StyledPostCard key={postPath} className="card main-content">
<StyledTitle> <StyledTitle>
<StyledLink to={pagePath}> <StyledLink to={postPath}>
{post.meta?.title {post?.title ? post.title : "Unknown title"}
? post.meta.title
: "Unknown title"}
</StyledLink> </StyledLink>
</StyledTitle> </StyledTitle>
<small> <small>
Published on{" "} Published on {post?.date ? post.date : "Unknown date"}
{post.meta?.date ? post.meta.date : "Unknown date"} by{" "}
{post.meta?.author
? post.meta.author
: "Unknown author"}
</small> </small>
<hr /> <hr />
<div <div
className="link-color" className="link-color"
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{
__html: marked( __html: marked(
post.content.split(" ").slice(0, 20).join(" ") + data.content.split(" ").slice(0, 20).join(" ") +
"..." "..."
), ),
}} }}
></div> ></div>
<small> <small>
<StyledLink to={pagePath}>Read more</StyledLink> <StyledLink to={postPath}>Read more</StyledLink>
</small> </small>
</StyledPostCard> </StyledPostCard>
) )
howMany-- howMany--
} }
this.setState({
PostCards: PostCards,
})
} }
render() { render() {
@ -116,18 +131,16 @@ export default class PostList extends React.Component<HomeProps> {
<meta property="og:title" content={this.props.title} /> <meta property="og:title" content={this.props.title} />
<meta property="og:type" content="website" /> <meta property="og:type" content="website" />
<meta property="og:url" content="http://developomp.com" />
<meta <meta
property="og:image" property="og:image"
content="http://developomp.com/icon/icon.svg" content={`${process.env.PUBLIC_URL}/icon/icon.svg`}
/> />
<meta property="og:description" content="" />
</Helmet> </Helmet>
<StyledPostList> <StyledPostList>
<StyledH1>{this.h1Text}</StyledH1> <StyledH1>{this.state.h1Text}</StyledH1>
<br /> <br />
{this.PostCards} {this.state.PostCards}
</StyledPostList> </StyledPostList>
</> </>
) )