WOHOO actual dev scripts now
This commit is contained in:
parent
afdf62b7cb
commit
6e82e1fbe8
18 changed files with 634 additions and 763 deletions
69
src/index.ts
Normal file
69
src/index.ts
Normal file
|
@ -0,0 +1,69 @@
|
|||
import marked from "marked";
|
||||
import express from "express"
|
||||
import ejs from "ejs";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import jsdom from "jsdom";
|
||||
import IConfig from "@src/types/Config";
|
||||
|
||||
let config: IConfig = JSON.parse(fs.readFileSync(path.join(__dirname, '../', 'data', 'config.json'), 'utf-8'))
|
||||
let app = express();
|
||||
|
||||
// set view engine to ejs
|
||||
app.set("view engine", "ejs")
|
||||
app.set('views', path.join(__dirname, 'views', 'themes', config.theme))
|
||||
|
||||
// type for post object
|
||||
type Post = {
|
||||
file: string;
|
||||
title: string;
|
||||
parsedPost: string;
|
||||
rawPost: string;
|
||||
metadata: fs.Stats;
|
||||
}
|
||||
|
||||
// html stripper, used for title
|
||||
async function htmlstripper(html: string){
|
||||
return new jsdom.JSDOM(html).window.document.body.textContent || " ";
|
||||
}
|
||||
|
||||
// returns Post array
|
||||
async function contentScan(){
|
||||
let posts: Post[] = []
|
||||
let postsDir = path.join(__dirname, '../', 'data',"posts")
|
||||
let files = await fs.readdirSync(postsDir).filter((name: string) => name.toLowerCase().endsWith(".md"))
|
||||
for (const file of files) {
|
||||
let postPath = path.join(postsDir, file)
|
||||
let metadata = fs.statSync(postPath)
|
||||
let postContent = fs.readFileSync(postPath, "utf-8")
|
||||
posts.push(
|
||||
{
|
||||
file: file,
|
||||
title: await htmlstripper(
|
||||
await marked.parse(
|
||||
postContent.split("\n")[0]
|
||||
)
|
||||
),
|
||||
metadata: metadata,
|
||||
parsedPost: await marked.parse(postContent),
|
||||
rawPost: postContent
|
||||
}
|
||||
)
|
||||
}
|
||||
return posts;
|
||||
}
|
||||
|
||||
app.get("/", async (req:express.Request,res:express.Response) => {
|
||||
res.render(`index`, {posts: (await contentScan()), config: config})
|
||||
});
|
||||
|
||||
app.use("/post/:post", async (req:express.Request,res:express.Response) => {
|
||||
let pathToPost = path.join(__dirname, '../', 'data', "posts", req.params.post);
|
||||
if(!fs.existsSync(pathToPost)) return res.end("404.");
|
||||
let posts = await contentScan();
|
||||
let post = posts.filter(post => post.file === req.params.post)
|
||||
if(!post[0]) return res.end("404.")
|
||||
res.render(`post`, {posts: posts, post: post[0], config: config})
|
||||
})
|
||||
|
||||
app.listen(3024)
|
7
src/types/Config.ts
Normal file
7
src/types/Config.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
export interface Branding {
|
||||
title: string;
|
||||
}
|
||||
export default interface Config {
|
||||
branding: Branding;
|
||||
theme: string;
|
||||
}
|
3
src/views/themes/default/footer.ejs
Normal file
3
src/views/themes/default/footer.ejs
Normal file
|
@ -0,0 +1,3 @@
|
|||
<div id="footer-content">
|
||||
<a href="https://git.clatter.cc/hexlocation/disseminate">powered by Disseminate</a>
|
||||
</div>
|
55
src/views/themes/default/global-style.ejs
Normal file
55
src/views/themes/default/global-style.ejs
Normal file
|
@ -0,0 +1,55 @@
|
|||
<style>
|
||||
@import url(https://fonts.bunny.net/css?family=alef:400);
|
||||
#main-content, #header-content {
|
||||
margin-top: 50px;
|
||||
margin: auto;
|
||||
width: 50%;
|
||||
}
|
||||
#main-content {
|
||||
text-align: left;
|
||||
}
|
||||
#header-content {
|
||||
text-align: center;
|
||||
}
|
||||
#link-container a {
|
||||
color: #808080 !important;
|
||||
}
|
||||
#link-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 20px;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
* {
|
||||
color:white;
|
||||
font-family: 'Arial', sans-serif;
|
||||
}
|
||||
a {
|
||||
text-decoration: none;
|
||||
decoration: none;
|
||||
color: orange;
|
||||
}
|
||||
table td {
|
||||
color: orange;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
#date-header, .date-item {
|
||||
text-align: right;
|
||||
}
|
||||
#title-header, .post-item {
|
||||
text-align: left;
|
||||
}
|
||||
#footer-content {
|
||||
position: fixed;
|
||||
bottom: 5;
|
||||
left: 0;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
body {
|
||||
background-color: #171717;
|
||||
}
|
||||
</style>
|
9
src/views/themes/default/header.ejs
Normal file
9
src/views/themes/default/header.ejs
Normal file
|
@ -0,0 +1,9 @@
|
|||
<div id="header-content">
|
||||
<h1><%= config.branding.title %></h1>
|
||||
<hr>
|
||||
<div id="link-container">
|
||||
<a href="/">home</a>
|
||||
<a href="/post/about.md">about</a>
|
||||
<a href="/post/contact.md">contact</a>
|
||||
</div>
|
||||
</div>
|
24
src/views/themes/default/index.ejs
Normal file
24
src/views/themes/default/index.ejs
Normal file
|
@ -0,0 +1,24 @@
|
|||
<%- include('header') %>
|
||||
<div id="main-content">
|
||||
<table id="posts-table">
|
||||
<!---
|
||||
<tr>
|
||||
<th id="title-header">Title</th>
|
||||
<th id="date-header">Last Edited</th>
|
||||
</tr>
|
||||
--->
|
||||
<% posts = posts.sort((a,b) => {return new Date(b.metadata.mtime) - new Date(a.metadata.mtime)}) %>
|
||||
<% for(const post of posts) { %>
|
||||
<tr>
|
||||
<td class="post-item"><a class="post" href="/post/<%= post.file %>"><%= post.title %></a></td>
|
||||
<td class="date-item"><%= new Date(post.metadata.mtime).toDateString() %></td>
|
||||
</tr>
|
||||
<% } %>
|
||||
</div>
|
||||
<style>
|
||||
#main-content {
|
||||
font-size: 15px;
|
||||
}
|
||||
</style>
|
||||
<%- include('global-style'); %>
|
||||
<%- include('footer') %>
|
6
src/views/themes/default/post.ejs
Normal file
6
src/views/themes/default/post.ejs
Normal file
|
@ -0,0 +1,6 @@
|
|||
<%- include('header') %>
|
||||
<div id="main-content">
|
||||
<%- post['parsedPost'] %>
|
||||
</div>
|
||||
<%- include('global-style') %>
|
||||
<%- include('footer') %>
|
Reference in a new issue