From cc131798a30c229938cf894f8e47b346b269ab9a Mon Sep 17 00:00:00 2001 From: DeaDvey Date: Tue, 22 Jul 2025 00:17:00 +0100 Subject: [PATCH] ejs stuff --- .nfs0000000000542e1500000001 | Bin 0 -> 12288 bytes README.md | 44 ++++-------- app.js | 131 +++++++++++++++++++---------------- custom.css | 1 + ejs-templates.js | 1 + example-config.json | 6 +- example-custom.css | 3 + functions.js | 10 +++ package.json | 1 + views/headers/tag.ejs | 4 ++ views/headers/timeline.ejs | 13 ++++ views/headers/user.ejs | 4 ++ views/pages/post.ejs | 14 ++++ views/pages/tag.ejs | 23 ++++++ views/pages/timeline.ejs | 19 +++++ views/pages/user.ejs | 21 ++++++ views/partials/comment.ejs | 2 + views/partials/footer.ejs | 2 + views/partials/head.ejs | 8 +++ views/posts/post.ejs | 29 ++++++++ views/posts/tag.ejs | 21 ++++++ views/posts/timeline.ejs | 23 ++++++ views/posts/user.ejs | 20 ++++++ 23 files changed, 311 insertions(+), 89 deletions(-) create mode 100644 .nfs0000000000542e1500000001 create mode 120000 custom.css create mode 100644 ejs-templates.js create mode 100644 example-custom.css create mode 100644 functions.js create mode 100644 views/headers/tag.ejs create mode 100644 views/headers/timeline.ejs create mode 100644 views/headers/user.ejs create mode 100644 views/pages/post.ejs create mode 100644 views/pages/tag.ejs create mode 100644 views/pages/timeline.ejs create mode 100644 views/pages/user.ejs create mode 100644 views/partials/comment.ejs create mode 100644 views/partials/footer.ejs create mode 100644 views/partials/head.ejs create mode 100644 views/posts/post.ejs create mode 100644 views/posts/tag.ejs create mode 100644 views/posts/timeline.ejs create mode 100644 views/posts/user.ejs diff --git a/.nfs0000000000542e1500000001 b/.nfs0000000000542e1500000001 new file mode 100644 index 0000000000000000000000000000000000000000..9e0ac120e42661ee3850a69fae380ea62cde8d1f GIT binary patch literal 12288 zcmYc?2=nw+u+%eTU|?VnU|?7iQeel#`#Ho?4`vm!FcFRjeQ6>geL@s+XGrQ9nwKhQMeDP$>jTOVV^L zco~e13=KdgDk~`}2n&URn4@?!1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(goHpz0V6{_ z0|NsS)W6_y00ssIMkpUfL%E~WXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeD zjE2Av41vTH28Oj93=Ex|kokXD|9>_=149u%1A_xU1H&Ia28Q2!3=D7h7#L>rF)+;H zV_@j#V_>l0V_?wcV_*>CV_@LnV_>+-%fN7umw{m$F9XADUIvC%UIvB?UIvDAUIvB) zUIqpiUIqpYUIqqrUIqp(UIvD5JPZuyc^DYh@-Q$g=V4&zo11~5l$(Jeg`0sPnVW&ZkDGx(gqwlkJ{JSSF)jv%TrLI%TP_BM z|C|gAS2-d6dBe%TaF~;UVKXNKLoX)-Lop`VBq6mVEDz(!0?lO2uA3rlSe~fGz3ONU^E0qLjZ3GXep>hDd;LVmXs7_ zCY6?C=I1GBU=hP2giV=7NxnjEs-{9>UW!6-erZv1ssd=0pF&P%UN%@TCo?%UuQ-)K zOF=b~>SkgykT?fn(TPO}x9{*M#wCSaTuUK2KQ}iuuS7vtAu&%OKPf9UxkRD3B)=## zFI}M|0~DTMc^!q+beLMbyu{p89XKyJKd&S;uY^HaS-}}%Sh0eJepzN}d9i*$Vo^zE zVotF>)Ed3itYS?DErrayl++4{otb$h3MCndB??8UX{klU3MKhqdm$?F)4-hM(xM`e zBMb72OBl2iN{dsA6m-EdP!~hhfhEc_@)bY|Q&SX5GBS%9w7@)wWl-f{`!e&Ab4pWE zi^1lkB$gy9q~#YuoC4Ag_A!W|SCUzhld1zYMGxv(h18N{kcR{Ei%XDv3*za6{Fjkg zlAK=(4%V{7oYGW<%sd5{m|jUmiGoI=LUCqZdQPfBUTJPpY7t0Na(-S~X1ZQkVo_#d zQch|-D3}#=6$%oIixm>{DivT7Aj6<)vx@Wc7?c%Uy@C<4AZ^7A42Y;LNK8*Hwg(C1 zq$cJmlomiTNuokhCMY!1Gs{vHQWKLiz&=z+RLDpyN&&MyT|lu>P?TB*34BmAXC~$- zWEK~frh)=CGcPAI51vLqu1rx#$xjAJ6&K`WmOw1Z%qz)PNXyIt1$DkcNoGo=LS_lb z84wpJC@3gsfx|CAh2+xWlKfnS;u26I1exWSlLO-^Xh5P3lsq%@6jD<%OTZZ& z6j2Hwk7`1-XBLCZV$f1ZOHD~FN`#a&Ir;h7#R?@wnaSCepb$?i$|FEvFWEj6*Ev?#S$za&2;Um+*6xC9i31x5Ku ziAgz?3YmGusmY~9sS1h33K^+6IiO?>lPgY61O;wRW_GGVaYkkdgR+8CX*xI!6lbP` zV;odMrljVimZT~qCWDhEgBC2ig2FOC4;x#rbI^<%vb$q9GBSs;m^Ep=;IklJj$8H8M&{3W}}t^^pWMZIX)g?HB@b zQWJ|)6;kr^)Js4i11{(kDpN~z6f#THixu+nOBB*F^D>JwQd1y09P?5X5_57Cz~x+K zF}R3NO##PkPGV+WNoqw2L}5rqX0bwMu|lE(c$qvXZ4_sgq$-pbWtNnr=7DrT*3IjH r%>zYYu>!~&;IK_mNXaZpO)kl)R7k1>dlRBqAt^CAJ2fvw4`K-bK=A{s literal 0 HcmV?d00001 diff --git a/README.md b/README.md index 16d7275..778e86c 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ See the software in action: [deadvey.com](https://deadvey.com)
# Confiuration Read the [configuation guide](CONFIG.md) for configuration help (in config.json) -# features +# Features * post creation via the web frontend (no need to remote to your server to make a post) * multi user * powerful customisation @@ -17,17 +17,16 @@ Read the [configuation guide](CONFIG.md) for configuration help (in config.json) * Markdown syntax in posts * Commenting on posts * sign up and delete account +* ejs # Bugs * probably scales like shit * probably insecure as hell -# planned features/todo list +# Planned features/todo list * custom CSS _file_ * custom strings use format indicators * seperate functions into modules -* builtin crypto -* ejs * user specific RSS feeds * atom * federation (looks tricky) @@ -37,30 +36,15 @@ Read the [configuation guide](CONFIG.md) for configuration help (in config.json) * inline comments and docs * give each post a hard postID to prevent potential issues * clean up code a bit +* comment pages? -# format indicators -* %% - A literal % -* %A - List of tags -* %B - List of tags, each one with a hyperlink to that tag page -* %C - Post content -* %D - Published date in the format specified by date_format -* %E - Edited date in the format specified by date_format -* %F - Pretty name -* %G - Tag name (used for the tag page only) -* %H - Frontpage hit count -* %I - User description -* %J - URL delete account -* %L - URL Permanent link to the post -* %M - comments -* %N - the username of the user (poster) -* %P - URL to create a new post -* %O - URL to edit this post -* %Q - URL to sign up -* %R - Site wide RSS feed -* %S - post seperator as defined by post_seperator -* %T - Title -* %U - URL the the user (poster) -* %W - Site Description as defined by site_description -* %X - Comment submission box -* %Y - Site Name as defined by site_name -* %Z - Attribution (to me) and source code link and license +TODO (not finished) +# EJS variable names +* config.variable_name - pass any variable in config.json +* hitcount - value in hitcount.txt (a single number) +## Posts (/views/posts/) +* post - an object that includes the data for that post, eg post.title, post.content etc +* user - the object of the user who posted this +* index - an int that refers to the index of the current post +## Comments (/views/partials/comment.ejs) +* comment - an object storing the comment, eg comment.name, comment.content diff --git a/app.js b/app.js index 36fc436..4006924 100755 --- a/app.js +++ b/app.js @@ -6,8 +6,10 @@ const crypto = require('crypto'); // For encrypting passwords, I use sha512 // fromUnixTime(): Create a date from a Unix timestamp (in seconds). Decimal values will be discarded. // format(): Return the formatted date string in the given format. The result may vary by locale. // getUnixTime(): Get the seconds timestamp of the given date. -// find out more at https://date-fns.org/ \or docs: https://date-fns.org/docs/Getting-Startedyyyyyyyy +// find out more at https://date-fns.org/ \or docs: https://date-fns.org/docs/Getting-Started const { fromUnixTime, format, getUnixTime } = require("date-fns") // A date utility library +const ejs = require("ejs") +const func = require("./functions.js") // There's only one possible argument, so we can just check if the user passed that one // TODO I plan on adding more such as --help and --post so I should make this more robust at some point @@ -20,6 +22,7 @@ let users // contains a list of users, each user is an object containing usernam let posts // contains a list of posts, let comments // contains a list of comments let config // contains a set of configuration for the site, see example-config.js for an example +let ejs_templates try { // We're going to try and import the modules, @@ -27,6 +30,7 @@ try { posts = require('./posts.json'); comments = require('./comments.json'); config = require('./config.json'); + ejs_templates = require("./ejs-templates.js") } catch (error) { // if they don't all import then @@ -56,6 +60,9 @@ const app = express(); app.use(express.urlencoded({ extended: true })); app.use(express.json()); app.use(express.static(config.root_path)); +// set the view engine to ejs +app.set('view engine', 'ejs'); + // Initialise the program by creating users.js, comments.js, posts.js and config.js // All require default content in them to start off with // Then exit successfully @@ -110,16 +117,6 @@ function get_userID(username) { return -1 // If user is not present, return -1 } -// The configuration defines a date format using the date-fns (a datetime library) syntax -// eg "yyyy-MM-dd" -// this converts unix time (an integer) into a string that is formatted according to config.js -// uses date-fns's fromUnixTime() and format() functions -// returns the formatted date (string) -function unix_time_to_date_format(unix_time) { - date = fromUnixTime(unix_time) - formatted_date = format(date, config.date_format) - return formatted_date -} // This is similar to the above function, however, instead of formatting to the users // configuration, it formats to RFC-822 which is the date format used by RSS feeds @@ -173,8 +170,8 @@ function replace_format_indicators(template, post_index=-1, tag_name="tag", user .replaceAll("%A", (post_object["tags"])) .replaceAll("%B", (hyperlink_tags(post_object["tags"]))) .replaceAll("%C", converter.makeHtml(post_object["content"])) - .replaceAll("%D", unix_time_to_date_format(post_object["pubdate"])) - .replaceAll("%E", unix_time_to_date_format(post_object["editdate"])) + //.replaceAll("%D", unix_time_to_date_format(post_object["pubdate"])) + //.replaceAll("%E", unix_time_to_date_format(post_object["editdate"])) .replaceAll("%F", users[post_object["userID"]]['prettyname']) .replaceAll("%G", tag_name) .replaceAll("%I", converter.makeHtml(users[post_object['userID']]['description'])) @@ -235,13 +232,13 @@ function return_comments(post_id) { .replaceAll(/>> ([0-9]*)/g, ">> $1") .replaceAll(/>> ([0-9]*)/g, ">> $1") .replaceAll("\n", "
") - comment_content += `
${comment['name']} ${unix_time_to_date_format(comment['pubdate'])} No. ${comment['id']}
${comment['content']}

` + //comment_content += `
${comment['name']} ${unix_time_to_date_format(comment['pubdate'])} No. ${comment['id']}
${comment['content']}

` } return comment_content } // RSS protocol gets -app.get(config.rss_path, (req,res) => { +app.get(config.rss_url, (req,res) => { if (config.rss == false) { res.send("Sorry, RSS is disabled!") } @@ -275,6 +272,7 @@ app.get(config.rss_path, (req,res) => { }); app.get("/", (req,res) => { + // Increment the hitcount if (config.enable_hitcount) { let hitcount = parseInt(fs.readFileSync('hitcount.txt')) hitcount += 1 @@ -282,51 +280,68 @@ app.get("/", (req,res) => { fs.writeFileSync(`${__dirname}/hitcount.txt`, `${hitcount}`, 'utf-8'); } - header_div = config.timeline_header - header_div = replace_format_indicators(header_div); - posts_div = ""; - counter = posts.length - 1; - while ((counter >= 0) && (counter > (posts.length - (config.timeline_length + 1)))) - { - let post = config.timeline_post_format; - posts_div += replace_format_indicators(post, counter); - counter -= 1; - } - res.send(`
${posts_div}
${footer_div}
`); + res.render("pages/timeline", + { + config: config, + posts: posts, + users: users, + comments: comments.comments, + hitcount: fs.readFileSync("hitcount.txt"), + fromUnixTime: fromUnixTime, + format: format, + getUnixTime: getUnixTime, + hyperlink_tags: hyperlink_tags, + }) }); // / app.get("/user/:username", (req, res) => { - header_div = config.user_page_header - header_div = replace_format_indicators(header_div,-1,"tag",get_userID(req.params.username)) - posts_div = ""; - for (let post_index = posts.length-1; post_index >= 0; post_index--) { - if (users[posts[post_index]["userID"]]["username"] == req.params.username) { - let post = config.user_post_format; - posts_div += replace_format_indicators(post, post_index); - } - } - res.send(`
${posts_div}
${footer_div}
`); + const userID = get_userID(req.params.username) + console.log(userID) + console.log(users[userID].prettyname) + res.render("pages/user", + { + config: config, + posts: posts, + user: users[userID], + userID: userID, + comments: comments.comments, + fromUnixTime: fromUnixTime, + format: format, + getUnixTime: getUnixTime, + hyperlink_tags: hyperlink_tags, + }) }); // /user/:username app.get("/post/:post_index", (req, res) => { - post_div = ""; - let post = config.post_page_format; - post_div += replace_format_indicators(post, req.params.post_index); - res.send(`
${post_div}
${footer_div}
`); + const postID = req.params.post_index + res.render("pages/post", + { + config, + post: posts[postID], + postID: postID, + user: users[posts[postID].userID], + comments: comments.comments[postID], + fromUnixTime, + format, + getUnixTime, + hyperlink_tags, + }) }); // /post/:post_index app.get("/tag/:tag", (req,res) => { - const tag = req.params.tag - let header_div = config.tag_page_header - header_div = replace_format_indicators(header_div,0,tag) - let page_content = "" - for (let i = posts.length-1; i >= 0; i--) { - if (posts[i]['tags'].includes(tag)) { - let post = config.tag_post_format; - page_content += replace_format_indicators(post, i); - }; - }; - res.send(`
${page_content}
${footer_div}
`); + const tag = req.params.tag + res.render("pages/tag", + { + config: config, + tag: tag, + posts: posts, + users: users, + comments: comments.comments, + fromUnixTime: fromUnixTime, + format: format, + getUnixTime: getUnixTime, + hyperlink_tags: hyperlink_tags, + }) }); // /tag/:tag -app.get("/post", (req,res) => { +app.get(config.new_post_url, (req,res) => { res.send(`


@@ -337,7 +352,7 @@ app.get("/post", (req,res) => { * Markdown supported
`); }); // /post -app.get("/signup", (req,res) => { +app.get(config.signup_url, (req,res) => { // if the server does allow signup if (config.allow_signup == true) { // Send the page for signing up to the server @@ -359,14 +374,14 @@ app.get("/signup", (req,res) => { console.log("Error, invalid value for allow_signup (bool)") } }); // /signup -app.get("/delete_account", (req,res) => { +app.get(config.delete_account_url, (req,res) => { res.send(`




`); }); // /delete_account -app.get("/edit/:post_id", (req,res) => { +app.get(`${config.edit_post_base_url}/:post_id`, (req,res) => { const post_id = req.params.post_id const post = posts[post_id] const user = users[post['userID']] @@ -409,13 +424,13 @@ app.post("/submit_post", (req,res) => { const content = escape_input(req.body.content) const tags = escape_input(req.body.tags).split(','); const unix_timestamp = getUnixTime(new Date()) - console.log(username, "is submitting a post titled:", title); if (get_userID(username) == -1) { - res.send("User does not exist") + res.send(`${config.user_doesnt_exit}`) } else if (users[get_userID(username)]['hash'] == password) { // Password matches + console.log(username, "is submitting a post titled:", title); posts.push({ "userID": get_userID(username), "title": title, @@ -430,7 +445,7 @@ app.post("/submit_post", (req,res) => { res.redirect(302, "/"); } else { - res.send(`Invalid Password for user`,username); + res.send(`${config.incorrect_password}`) } }); // /submit_post app.post("/submit_signup", (req,res) => { diff --git a/custom.css b/custom.css new file mode 120000 index 0000000..ecac342 --- /dev/null +++ b/custom.css @@ -0,0 +1 @@ +example-custom.css \ No newline at end of file diff --git a/ejs-templates.js b/ejs-templates.js new file mode 100644 index 0000000..c893a17 --- /dev/null +++ b/ejs-templates.js @@ -0,0 +1 @@ +export let timeline = '
${posts_div}
${footer_div}
' diff --git a/example-config.json b/example-config.json index 37d44ee..e2ed85b 100755 --- a/example-config.json +++ b/example-config.json @@ -9,9 +9,13 @@ "enable_hitcount": true, "charset": "UTF-8", "root_path": "/path/to/root/of/website", + "delete_account_url": "/delete_account", + "new_post_url": "/post", + "signup_url": "/signup", + "edit_post_base_url": "/edit", "default_comenter_username": "Anon", "rss": true, - "rss_path": "/rss", + "rss_url": "/rss", "date_format": "yyyy-MM-dd", "time_zone": "+0000", "timeline_header": "

%Y

%W

Create Post
RSS Feed
Sign Up
Delete Account
Hit count: %H%S", diff --git a/example-custom.css b/example-custom.css new file mode 100644 index 0000000..5e2752a --- /dev/null +++ b/example-custom.css @@ -0,0 +1,3 @@ +body { + /* Put your custom css here */ +} diff --git a/functions.js b/functions.js new file mode 100644 index 0000000..46a182a --- /dev/null +++ b/functions.js @@ -0,0 +1,10 @@ +// The configuration defines a date format using the date-fns (a datetime library) syntax +// eg "yyyy-MM-dd" +// this converts unix time (an integer) into a string that is formatted according to config.js +// uses date-fns's fromUnixTime() and format() functions +// returns the formatted date (string) +export function unix_time_to_date_format(unix_time, format) { + date = fromUnixTime(unix_time) + formatted_date = format(date, format) + return formatted_date +} diff --git a/package.json b/package.json index c02b2a9..95052f9 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "dependencies": { "date-fns": "^4.1.0", + "ejs": "^3.1.10", "express": "^5.1.0", "showdown": "^2.1.0" } diff --git a/views/headers/tag.ejs b/views/headers/tag.ejs new file mode 100644 index 0000000..2ba4e40 --- /dev/null +++ b/views/headers/tag.ejs @@ -0,0 +1,4 @@ +

+ Post's tagged "<%- tag %>": +

+<%- config.seperator %> diff --git a/views/headers/timeline.ejs b/views/headers/timeline.ejs new file mode 100644 index 0000000..159fe9e --- /dev/null +++ b/views/headers/timeline.ejs @@ -0,0 +1,13 @@ +

+ <%- config.site_name %> +

+

+ <%- config.site_description %> +

+RSS Feed
+Sign Up
+Delete Account
+<% if (config.enable_hitcount == true) { %> +Hitcount: <%= hitcount %> +<% } %> +<%- config.seperator %> diff --git a/views/headers/user.ejs b/views/headers/user.ejs new file mode 100644 index 0000000..949aefc --- /dev/null +++ b/views/headers/user.ejs @@ -0,0 +1,4 @@ +

+ <%- user.prettyname %>'s posts +

+<%- config.seperator %> diff --git a/views/pages/post.ejs b/views/pages/post.ejs new file mode 100644 index 0000000..85c2917 --- /dev/null +++ b/views/pages/post.ejs @@ -0,0 +1,14 @@ + + + + <%- include('../partials/head'); %> + + +
+ <%- include('../posts/post'); %> +
+
+ <%- include('../partials/footer'); %> +
+ + diff --git a/views/pages/tag.ejs b/views/pages/tag.ejs new file mode 100644 index 0000000..fc54ed8 --- /dev/null +++ b/views/pages/tag.ejs @@ -0,0 +1,23 @@ + + + + <%- include('../partials/head'); %> + + + +
+ <% for (let index = posts.length - 1; index >= 0; index--) { %> + <% posts[index].tags.forEach((current_tag, tag_index) => { %> + <% if (current_tag == tag) { %> + <%- include('../posts/tag', {post: posts[index], postID: index}); %> + <% } %> + <% }) %> + <% } %> +
+
+ <%- include('../partials/footer'); %> +
+ + diff --git a/views/pages/timeline.ejs b/views/pages/timeline.ejs new file mode 100644 index 0000000..4df5505 --- /dev/null +++ b/views/pages/timeline.ejs @@ -0,0 +1,19 @@ + + + + <%- include('../partials/head'); %> + + + +
+ <% for (let index = posts.length - 1; index >= 0; index--) { %> + <%- include('../posts/timeline', {post: posts[index], index: index, user: users[posts[index].userID]}); %> + <% } %> +
+
+ <%- include('../partials/footer'); %> +
+ + diff --git a/views/pages/user.ejs b/views/pages/user.ejs new file mode 100644 index 0000000..6d386c7 --- /dev/null +++ b/views/pages/user.ejs @@ -0,0 +1,21 @@ + + + + <%- include('../partials/head'); %> + + + +
+ <% for (let index = posts.length - 1; index >= 0; index--) { %> + <% if (posts[index].userID == userID) { %> + <%- include('../posts/user', {post: posts[index], index: index, user: user}); %> + <% } %> + <% } %> +
+
+ <%- include('../partials/footer'); %> +
+ + diff --git a/views/partials/comment.ejs b/views/partials/comment.ejs new file mode 100644 index 0000000..7f94274 --- /dev/null +++ b/views/partials/comment.ejs @@ -0,0 +1,2 @@ +<%= comment.name %> <%= format(fromUnixTime(comment.pubdate), config.date_format) %> No. <%= comment.id %>:
+<%= comment.content %> diff --git a/views/partials/footer.ejs b/views/partials/footer.ejs new file mode 100644 index 0000000..8710c02 --- /dev/null +++ b/views/partials/footer.ejs @@ -0,0 +1,2 @@ +Site is ran by deadvey
+<%- config.attribution %> diff --git a/views/partials/head.ejs b/views/partials/head.ejs new file mode 100644 index 0000000..9d29ced --- /dev/null +++ b/views/partials/head.ejs @@ -0,0 +1,8 @@ + +<%= config.site_name %> + + + + diff --git a/views/posts/post.ejs b/views/posts/post.ejs new file mode 100644 index 0000000..4f8cd28 --- /dev/null +++ b/views/posts/post.ejs @@ -0,0 +1,29 @@ +

+ <%= post.title %> +

+<%= post.content %>
+ + By <%= user.username %>
+
+
+<%- hyperlink_tags(post.tags) %>
+Edit
+Published: <%= format(fromUnixTime(post.pubdate), config.date_format) %>
+Last Modified: <%= format(fromUnixTime(post.editdate), config.date_format) %>
+ +<%- config.seperator %> + + +
+ +
+
+ +
+ +<% comments.forEach((comment, postID) => { %> + <%- include('../partials/comment', {comment: comment}) %> +<% }) %> + +<%- config.seperator %> + diff --git a/views/posts/tag.ejs b/views/posts/tag.ejs new file mode 100644 index 0000000..e1ea9c7 --- /dev/null +++ b/views/posts/tag.ejs @@ -0,0 +1,21 @@ +

+ <%= post.title %> +

+<%= post.content %>
+Permalink
+<%- hyperlink_tags(post.tags) %> + + +
+ +
+
+ +
+ +<% comments[postID].forEach((comment) => { %> + <%- include('../partials/comment', {comment: comment}) %> +<% }) %> + +<%- config.seperator %> + diff --git a/views/posts/timeline.ejs b/views/posts/timeline.ejs new file mode 100644 index 0000000..6951340 --- /dev/null +++ b/views/posts/timeline.ejs @@ -0,0 +1,23 @@ +

+ <%= post.title %> +

+<%= post.content %>
+Permalink
+ + By <%= user.username %>
+
+ + +
+ +
+
+ +
+ +<% comments[index].forEach((comment, index) => { %> + <%- include('../partials/comment', {comment: comment}) %> +<% }) %> + +<%- config.seperator %> + diff --git a/views/posts/user.ejs b/views/posts/user.ejs new file mode 100644 index 0000000..f449c02 --- /dev/null +++ b/views/posts/user.ejs @@ -0,0 +1,20 @@ +

+ <%= post.title %> +

+<%= post.content %>
+Permalink
+ + +
+ +
+
+ +
+ +<% comments[index].forEach((comment, index) => { %> + <%- include('../partials/comment', {comment: comment}) %> +<% }) %> + +<%- config.seperator %> +