diff options
Diffstat (limited to 'pages')
-rw-r--r-- | pages/_app.tsx | 1 | ||||
-rw-r--r-- | pages/blog/[post].tsx | 80 | ||||
-rw-r--r-- | pages/index.tsx | 45 |
3 files changed, 90 insertions, 36 deletions
diff --git a/pages/_app.tsx b/pages/_app.tsx index 418cacd..45e00ab 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -14,6 +14,7 @@ import '../styles/toast.css'; import '../styles/ui.css'; import '../styles/utility.css'; +import '../styles/blog.css'; import '../styles/game.css'; import '../styles/gameSettings.css'; import '../styles/index.css'; diff --git a/pages/blog/[post].tsx b/pages/blog/[post].tsx index 9ebd3ad..fe25007 100644 --- a/pages/blog/[post].tsx +++ b/pages/blog/[post].tsx @@ -1,58 +1,84 @@ import { readdirSync, readFileSync } from 'fs'; -import micromark from 'micromark'; import { join } from 'path'; +import ReactMarkdown from 'react-markdown'; +import rehypeRaw from 'rehype-raw'; +import gfm from 'remark-gfm'; + +import { Footer } from '../../components/footer'; import { NavBar } from '../../components/navbar'; import { CenteredPage, PageTitle } from '../../components/page'; import { Vierkant } from '../../components/ui'; +export interface ArticleMeta { + title?: string; + id?: string; +} + +export function RenderedArticle(props: { + content: string; + meta: ArticleMeta; + standalone?: boolean; +}) { + return <Vierkant className='pad-l bg-800 w100m2m postContent'> + <ReactMarkdown + rehypePlugins={[rehypeRaw]} + remarkPlugins={[gfm]} + children={(props.standalone ? '' : '## ' + props.meta.title + '\n\n') + props.content} + /> + </Vierkant>; +} + export default function Post(props: { - post: string; content: string; - tags: string; + meta: ArticleMeta; }) { return <div> <NavBar /> - <CenteredPage width={802}> - <PageTitle>{props.post.replace(/_/g, ' ')}</PageTitle> - <Vierkant fullwidth> - <div dangerouslySetInnerHTML={{ __html: props.content }}> - </div> - </Vierkant> + <CenteredPage width={802} className='blogPost'> + <PageTitle>{props.meta.title}</PageTitle> + <RenderedArticle content={props.content} meta={props.meta} standalone /> </CenteredPage> + <Footer /> </div>; } -function parseTags(fileContent: string) { - var fileAsArr = fileContent.split('\n'); - var lastLine = fileAsArr[fileAsArr.length - 1]; - if (!lastLine.startsWith(';tags:')) { - return { - tags: [], - result: '', - }; - } +var parseTag = { + 'title': (val: string) => val, +}; - var tags = lastLine.replace(';tags:', '').trim().split(' '); +function parseMeta(file: Array<string>): ArticleMeta { + var meta: ArticleMeta = {}; - fileAsArr.pop(); - var result = fileAsArr.join('\n').trim(); + file.forEach(line => { + if (!line.startsWith('[meta]: ')) return; + var tags = line.match(/\[meta\]:\s+\<(.+?)\>\s+\((.+?)\)/); + if (!tags || !tags[1] || !tags[2]) return; + if (!parseTag.hasOwnProperty(tags[1])) return; + meta[tags[1]] = parseTag[tags[1]](tags[2]); + }); + + return meta; +} - return { tags, result }; +function preprocessor(fileContent: string) { + var fileAsArr = fileContent.split('\n'); + var meta = parseMeta(fileAsArr); + var result = fileAsArr.join('\n').trim(); + return { meta, result }; } export function getStaticProps(props: { params: { post: string; }; }) { var filename = join('news/', props.params.post + '.md'); var filecontent = readFileSync(filename).toString().trim(); - var parsed = parseTags(filecontent); - var content = micromark(parsed.result); + var parsed = preprocessor(filecontent); + parsed.meta.id = props.params.post; return { props: { - post: props.params.post, - content, - tags: parsed.tags, + content: parsed.result, + meta: parsed.meta, }, }; } diff --git a/pages/index.tsx b/pages/index.tsx index c4b4baf..7d77269 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -16,6 +16,11 @@ import VideogameAssetIcon from '@material-ui/icons/VideogameAsset'; import { mdiRobotExcited } from '@mdi/js'; import Icon from '@mdi/react'; +import { ArticleMeta, getStaticProps as getBlogPage, RenderedArticle } from './blog/[post]'; + +// edit this to change the post displayed on the home page +var posts = ['cool_test_article']; + function LoginOrRegisterBox() { return <div className='inner'> <span className='registerMessage posabs h0 t0'> @@ -50,7 +55,14 @@ function AccountBox(props: { </div>; } -export default function HomePage() { +export default function HomePage(props: { + posts: Array<{ + props: { + content: string; + meta: ArticleMeta; + }; + }>; +}) { var server = typeof window === 'undefined'; var loggedIn = !server && document.cookie.includes('token'); @@ -113,15 +125,30 @@ export default function HomePage() { : <LoginOrRegisterBox />} </Vierkant> </div> - {loggedIn - && <Vierkant className='w100m2m pad-l bg-800'> - <RecentGames games={gameInfo?.games} /> - </Vierkant>} - <Vierkant className='w100m2m pad-l bg-800'> - <h2>Nieuws ofzo</h2> - <p style={{ margin: '6px 0' }}>Chess.com heeft heel veel troep waar niemand naar kijkt</p> - </Vierkant> + <> + {loggedIn + && <Vierkant className='w100m2m pad-l bg-800'> + <RecentGames games={gameInfo?.games} /> + </Vierkant>} + </> + <div> + {props.posts.map(post => { + return <RenderedArticle content={post.props.content} meta={post.props.meta} />; + })} + </div> </CenteredPage> <Footer /> </div>; } + +export function getStaticProps() { + var postsContent = []; + + posts.forEach(post => { + postsContent.push(getBlogPage({ params: { post } })); + }); + + var staticProps = { props: { posts: postsContent } }; + + return staticProps; +} |